summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuilhem Lavaux <guilhem@kaffe.org>2006-06-08 20:19:53 +0000
committerGuilhem Lavaux <guilhem@kaffe.org>2006-06-08 20:19:53 +0000
commit2f94810a11e0e3cdeb4bed695a4bf9eb9ce41c34 (patch)
treec5e2c0011d6dd129dbdc8da0273cdaff7b1bc3f6
parent56c5b96a2d3754736d13eebb73270fb8f925301d (diff)
downloadclasspath-native_layer_merge_head_2006_06_06.tar.gz
2006-06-07 Guilhem Lavaux <guilhem@kaffe.org>native_layer_merge_head_2006_06_06
* Merged HEAD as of 2006-06-06. * native/jni/native-lib/cpproc.h (CPIO_EXEC_NUM_PIPES): Compilation fix.
-rw-r--r--.externalToolBuilders/Configure.launch15
-rw-r--r--ChangeLog3417
-rw-r--r--ChangeLog.native7
-rw-r--r--INSTALL7
-rw-r--r--NEWS35
-rw-r--r--README3
-rw-r--r--THANKYOU1
-rw-r--r--configure.ac124
-rw-r--r--doc/www.gnu.org/announce/20060515.wml217
-rw-r--r--doc/www.gnu.org/downloads/downloads.wml14
-rw-r--r--doc/www.gnu.org/newsitems.txt5
-rw-r--r--examples/gnu/classpath/examples/awt/Demo.java95
-rw-r--r--examples/gnu/classpath/examples/swing/Demo.java10
-rw-r--r--examples/gnu/classpath/examples/swing/FillRect.java388
-rw-r--r--examples/gnu/classpath/examples/swing/NavigationFilterDemo.java5
-rw-r--r--examples/gnu/classpath/examples/swing/TableDemo.java180
-rw-r--r--gnu/classpath/Configuration.java.in6
-rw-r--r--gnu/classpath/jdwp/processor/ClassTypeCommandSet.java8
-rw-r--r--gnu/classpath/jdwp/processor/EventRequestCommandSet.java2
-rw-r--r--gnu/classpath/jdwp/processor/ThreadGroupReferenceCommandSet.java8
-rw-r--r--gnu/java/awt/BitwiseXORComposite.java2
-rw-r--r--gnu/java/awt/Buffers.java88
-rw-r--r--gnu/java/awt/font/GNUGlyphVector.java2
-rw-r--r--gnu/java/awt/font/opentype/NameDecoder.java46
-rw-r--r--gnu/java/awt/java2d/AbstractGraphics2D.java804
-rw-r--r--gnu/java/awt/java2d/AlphaCompositeContext.java2
-rw-r--r--gnu/java/awt/java2d/ImagePaint.java192
-rw-r--r--gnu/java/awt/java2d/RasterGraphics.java2
-rw-r--r--gnu/java/awt/java2d/TexturePaintContext.java205
-rw-r--r--gnu/java/awt/peer/gtk/BufferedImageGraphics.java258
-rw-r--r--gnu/java/awt/peer/gtk/CairoGraphics2D.java (renamed from gnu/java/awt/peer/gtk/GdkGraphics2D.java)1905
-rw-r--r--gnu/java/awt/peer/gtk/CairoSurface.java280
-rw-r--r--gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java100
-rw-r--r--gnu/java/awt/peer/gtk/ComponentGraphics.java220
-rw-r--r--gnu/java/awt/peer/gtk/ComponentGraphicsCopy.java129
-rw-r--r--gnu/java/awt/peer/gtk/GdkFontPeer.java97
-rw-r--r--gnu/java/awt/peer/gtk/GdkGraphics.java496
-rw-r--r--gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java29
-rw-r--r--gnu/java/awt/peer/gtk/GdkPixbufDecoder.java64
-rw-r--r--gnu/java/awt/peer/gtk/GdkTextLayout.java78
-rw-r--r--gnu/java/awt/peer/gtk/GtkCanvasPeer.java1
-rw-r--r--gnu/java/awt/peer/gtk/GtkComponentPeer.java32
-rw-r--r--gnu/java/awt/peer/gtk/GtkImage.java273
-rw-r--r--gnu/java/awt/peer/gtk/GtkToolkit.java55
-rw-r--r--gnu/java/awt/peer/gtk/GtkVolatileImage.java101
-rw-r--r--gnu/java/awt/peer/gtk/VolatileImageGraphics.java129
-rw-r--r--gnu/java/awt/peer/swing/SwingComponent.java6
-rw-r--r--gnu/java/awt/peer/swing/SwingComponentPeer.java43
-rw-r--r--gnu/java/awt/peer/swing/SwingContainerPeer.java9
-rw-r--r--gnu/java/awt/peer/swing/SwingFramePeer.java6
-rw-r--r--gnu/java/awt/peer/swing/SwingMenuBarPeer.java2
-rw-r--r--gnu/java/awt/peer/swing/SwingTextFieldPeer.java2
-rw-r--r--gnu/java/awt/peer/swing/SwingWindowPeer.java6
-rw-r--r--gnu/java/awt/print/JavaPrinterGraphics.java518
-rw-r--r--gnu/java/awt/print/JavaPrinterJob.java403
-rw-r--r--gnu/java/awt/print/PostScriptGraphics2D.java1349
-rw-r--r--gnu/java/awt/print/SpooledDocument.java91
-rw-r--r--gnu/java/lang/management/OperatingSystemMXBeanImpl.java73
-rw-r--r--gnu/java/lang/management/package.html46
-rw-r--r--gnu/java/net/IndexListParser.java62
-rw-r--r--gnu/java/net/loader/FileResource.java82
-rw-r--r--gnu/java/net/loader/FileURLLoader.java145
-rw-r--r--gnu/java/net/loader/JarURLLoader.java210
-rw-r--r--gnu/java/net/loader/JarURLResource.java94
-rw-r--r--gnu/java/net/loader/RemoteResource.java78
-rw-r--r--gnu/java/net/loader/RemoteURLLoader.java101
-rw-r--r--gnu/java/net/loader/Resource.java110
-rw-r--r--gnu/java/net/loader/URLLoader.java147
-rw-r--r--gnu/java/net/loader/URLStreamHandlerCache.java84
-rw-r--r--gnu/java/net/protocol/http/HTTPConnection.java5
-rw-r--r--gnu/java/net/protocol/http/HTTPURLConnection.java28
-rw-r--r--gnu/java/net/protocol/jar/Connection.java2
-rw-r--r--gnu/java/nio/PipeImpl.java32
-rw-r--r--gnu/java/nio/SelectorImpl.java2
-rw-r--r--gnu/java/nio/SocketChannelSelectionKeyImpl.java69
-rw-r--r--gnu/java/nio/channels/FileChannelImpl.java49
-rw-r--r--gnu/java/security/OID.java3
-rw-r--r--gnu/java/security/PolicyFile.java4
-rw-r--r--gnu/java/security/hash/MD4.java2
-rw-r--r--gnu/java/security/prng/PRNGFactory.java1
-rw-r--r--gnu/java/security/provider/PKIXCertPathValidatorImpl.java4
-rw-r--r--gnu/java/security/sig/ISignature.java4
-rw-r--r--gnu/java/security/sig/rsa/RSAPSSSignatureRawCodec.java2
-rw-r--r--gnu/java/security/util/ExpirableObject.java4
-rw-r--r--gnu/java/security/util/SimpleList.java2
-rw-r--r--gnu/java/security/x509/Util.java4
-rw-r--r--gnu/java/security/x509/ext/GeneralNames.java3
-rw-r--r--gnu/javax/crypto/assembly/Cascade.java2
-rw-r--r--gnu/javax/crypto/assembly/Direction.java4
-rw-r--r--gnu/javax/crypto/assembly/Transformer.java2
-rw-r--r--gnu/javax/crypto/cipher/BaseCipher.java2
-rw-r--r--gnu/javax/crypto/cipher/IBlockCipherSpi.java2
-rw-r--r--gnu/javax/crypto/jce/cipher/CipherAdapter.java4
-rw-r--r--gnu/javax/crypto/jce/key/AnubisSecretKeyFactoryImpl.java7
-rw-r--r--gnu/javax/crypto/jce/key/BlowfishSecretKeyFactoryImpl.java7
-rw-r--r--gnu/javax/crypto/jce/key/Cast5SecretKeyFactoryImpl.java7
-rw-r--r--gnu/javax/crypto/jce/key/KhazadSecretKeyFactoryImpl.java7
-rw-r--r--gnu/javax/crypto/jce/key/RijndaelSecretKeyFactoryImpl.java7
-rw-r--r--gnu/javax/crypto/jce/key/SerpentSecretKeyFactoryImpl.java7
-rw-r--r--gnu/javax/crypto/jce/key/SquareSecretKeyFactoryImpl.java7
-rw-r--r--gnu/javax/crypto/jce/key/TwofishSecretKeyFactoryImpl.java7
-rw-r--r--gnu/javax/crypto/jce/keyring/GnuKeyring.java105
-rw-r--r--gnu/javax/crypto/jce/mac/OMacImpl.java1
-rw-r--r--gnu/javax/crypto/jce/prng/CSPRNGSpi.java3
-rw-r--r--gnu/javax/crypto/jce/spec/TMMHParameterSpec.java2
-rw-r--r--gnu/javax/crypto/key/dh/GnuDHPrivateKey.java2
-rw-r--r--gnu/javax/crypto/keyring/AuthenticatedEntry.java17
-rw-r--r--gnu/javax/crypto/keyring/CertPathEntry.java3
-rw-r--r--gnu/javax/crypto/keyring/CertificateEntry.java2
-rw-r--r--gnu/javax/crypto/keyring/EncryptedEntry.java24
-rw-r--r--gnu/javax/crypto/keyring/Entry.java21
-rw-r--r--gnu/javax/crypto/keyring/EnvelopeEntry.java160
-rw-r--r--gnu/javax/crypto/keyring/GnuPrivateKeyring.java62
-rw-r--r--gnu/javax/crypto/keyring/GnuPublicKeyring.java15
-rw-r--r--gnu/javax/crypto/keyring/MaskableEnvelopeEntry.java18
-rw-r--r--gnu/javax/crypto/keyring/PasswordAuthenticatedEntry.java60
-rw-r--r--gnu/javax/crypto/keyring/PasswordEncryptedEntry.java64
-rw-r--r--gnu/javax/crypto/keyring/PrivateKeyEntry.java67
-rw-r--r--gnu/javax/crypto/keyring/PublicKeyEntry.java17
-rw-r--r--gnu/javax/crypto/mac/OMAC.java2
-rw-r--r--gnu/javax/crypto/mode/BaseMode.java2
-rw-r--r--gnu/javax/crypto/mode/CTR.java2
-rw-r--r--gnu/javax/crypto/pad/IPad.java2
-rw-r--r--gnu/javax/crypto/pad/PKCS1_V1_5.java2
-rw-r--r--gnu/javax/crypto/pad/PKCS7.java2
-rw-r--r--gnu/javax/crypto/pad/TBC.java2
-rw-r--r--gnu/javax/crypto/pad/TLS1.java2
-rw-r--r--gnu/javax/crypto/prng/CSPRNG.java11
-rw-r--r--gnu/javax/crypto/sasl/SaslUtil.java1
-rw-r--r--gnu/javax/crypto/sasl/srp/PasswordFile.java3
-rw-r--r--gnu/javax/crypto/sasl/srp/SRPRegistry.java2
-rw-r--r--gnu/javax/imageio/jpeg/DCT.java1
-rw-r--r--gnu/javax/imageio/jpeg/YCbCr_ColorSpace.java9
-rw-r--r--gnu/javax/imageio/jpeg/ZigZag.java1
-rw-r--r--gnu/javax/print/CupsServer.java31
-rw-r--r--gnu/javax/print/ipp/IppRequest.java12
-rw-r--r--gnu/javax/swing/text/html/CharacterAttributeTranslator.java156
-rw-r--r--gnu/javax/swing/text/html/CombinedAttributes.java213
-rw-r--r--gnu/javax/swing/text/html/ImageViewIconFactory.java282
-rw-r--r--gnu/xml/dom/DomNode.java3
-rw-r--r--include/Makefile.am13
-rw-r--r--include/gnu_java_awt_peer_gtk_CairoGraphics2D.h45
-rw-r--r--include/gnu_java_awt_peer_gtk_CairoSurface.h28
-rw-r--r--include/gnu_java_awt_peer_gtk_ComponentGraphics.h24
-rw-r--r--include/gnu_java_awt_peer_gtk_ComponentGraphicsCopy.h20
-rw-r--r--include/gnu_java_awt_peer_gtk_GdkFontPeer.h4
-rw-r--r--include/gnu_java_awt_peer_gtk_GdkGraphics.h47
-rw-r--r--include/gnu_java_awt_peer_gtk_GdkGraphics2D.h67
-rw-r--r--include/gnu_java_awt_peer_gtk_GdkTextLayout.h2
-rw-r--r--include/gnu_java_awt_peer_gtk_GtkCanvasPeer.h1
-rw-r--r--include/gnu_java_awt_peer_gtk_GtkComponentPeer.h2
-rw-r--r--include/gnu_java_awt_peer_gtk_GtkImage.h9
-rw-r--r--include/gnu_java_awt_peer_gtk_GtkVolatileImage.h22
-rw-r--r--include/gnu_java_nio_VMChannel.h24
-rw-r--r--include/java_net_VMURLConnection.h22
-rw-r--r--java/awt/BasicStroke.java2
-rw-r--r--java/awt/ColorPaintContext.java2
-rw-r--r--java/awt/Component.java55
-rw-r--r--java/awt/Container.java40
-rw-r--r--java/awt/ContainerOrderFocusTraversalPolicy.java173
-rw-r--r--java/awt/DefaultKeyboardFocusManager.java10
-rw-r--r--java/awt/EventDispatchThread.java22
-rw-r--r--java/awt/Font.java2
-rw-r--r--java/awt/Graphics2D.java222
-rw-r--r--java/awt/GraphicsConfiguration.java21
-rw-r--r--java/awt/LightweightDispatcher.java122
-rw-r--r--java/awt/TexturePaint.java55
-rw-r--r--java/awt/Toolkit.java2
-rw-r--r--java/awt/Window.java96
-rw-r--r--java/awt/dnd/DragGestureRecognizer.java13
-rw-r--r--java/awt/font/GlyphMetrics.java16
-rw-r--r--java/awt/font/GlyphVector.java61
-rw-r--r--java/awt/font/GraphicAttribute.java91
-rw-r--r--java/awt/font/ImageGraphicAttribute.java140
-rw-r--r--java/awt/font/ShapeGraphicAttribute.java128
-rw-r--r--java/awt/geom/GeneralPath.java14
-rw-r--r--java/awt/image/ColorModel.java61
-rw-r--r--java/awt/print/PrinterJob.java29
-rw-r--r--java/beans/beancontext/BeanContextSupport.java291
-rw-r--r--java/io/ObjectInputStream.java18
-rw-r--r--java/io/ObjectOutputStream.java17
-rw-r--r--java/io/ObjectStreamClass.java11
-rw-r--r--java/io/ObjectStreamConstants.java126
-rw-r--r--java/io/OutputStream.java4
-rw-r--r--java/lang/SecurityManager.java4
-rw-r--r--java/lang/System.java31
-rw-r--r--java/lang/Thread.java52
-rw-r--r--java/lang/ThreadGroup.java2
-rw-r--r--java/lang/annotation/IncompleteAnnotationException.java106
-rw-r--r--java/lang/management/ManagementFactory.java81
-rw-r--r--java/lang/management/OperatingSystemMXBean.java103
-rw-r--r--java/lang/management/package.html64
-rw-r--r--java/math/BigDecimal.java1125
-rw-r--r--java/math/BigInteger.java2
-rw-r--r--java/math/MathContext.java144
-rw-r--r--java/net/InetSocketAddress.java9
-rw-r--r--java/net/URLClassLoader.java733
-rw-r--r--java/net/URLConnection.java47
-rw-r--r--java/nio/ByteBufferImpl.java10
-rw-r--r--java/nio/CharBuffer.java12
-rw-r--r--java/nio/channels/FileChannel.java14
-rw-r--r--java/text/NumberFormat.java2
-rw-r--r--java/util/Collections.java9
-rw-r--r--java/util/DuplicateFormatFlagsException.java (renamed from native/jni/gtk-peer/gtkcairopeer.h)99
-rw-r--r--java/util/FormatFlagsConversionMismatchException.java111
-rw-r--r--java/util/Formattable.java92
-rw-r--r--java/util/FormattableFlags.java123
-rw-r--r--java/util/Formatter.java1294
-rw-r--r--java/util/FormatterClosedException.java60
-rw-r--r--java/util/IllegalFormatCodePointException.java85
-rw-r--r--java/util/IllegalFormatConversionException.java110
-rw-r--r--java/util/IllegalFormatException.java75
-rw-r--r--java/util/IllegalFormatFlagsException.java86
-rw-r--r--java/util/IllegalFormatPrecisionException.java85
-rw-r--r--java/util/IllegalFormatWidthException.java84
-rw-r--r--java/util/MissingFormatArgumentException.java90
-rw-r--r--java/util/MissingFormatWidthException.java88
-rw-r--r--java/util/SimpleTimeZone.java102
-rw-r--r--java/util/UnknownFormatConversionException.java86
-rw-r--r--java/util/UnknownFormatFlagsException.java88
-rw-r--r--java/util/jar/JarOutputStream.java2
-rw-r--r--java/util/jar/Manifest.java4
-rw-r--r--java/util/logging/FileHandler.java75
-rw-r--r--java/util/logging/LogManager.java6
-rw-r--r--java/util/logging/Logger.java19
-rw-r--r--javax/accessibility/AccessibleContext.java2
-rw-r--r--javax/imageio/stream/ImageInputStreamImpl.java195
-rw-r--r--javax/imageio/stream/MemoryCacheImageInputStream.java43
-rw-r--r--javax/naming/CompositeName.java9
-rw-r--r--javax/naming/CompoundName.java4
-rw-r--r--javax/naming/Context.java558
-rw-r--r--javax/naming/ContextNotEmptyException.java7
-rw-r--r--javax/naming/InitialContext.java424
-rw-r--r--javax/naming/NameParser.java22
-rw-r--r--javax/naming/NamingEnumeration.java49
-rw-r--r--javax/naming/PartialResultException.java6
-rw-r--r--javax/naming/Reference.java158
-rw-r--r--javax/naming/Referenceable.java14
-rw-r--r--javax/naming/SizeLimitExceededException.java7
-rw-r--r--javax/naming/spi/InitialContextFactory.java23
-rw-r--r--javax/naming/spi/InitialContextFactoryBuilder.java17
-rw-r--r--javax/naming/spi/NamingManager.java394
-rw-r--r--javax/naming/spi/ObjectFactory.java32
-rw-r--r--javax/naming/spi/ObjectFactoryBuilder.java26
-rw-r--r--javax/naming/spi/ResolveResult.java82
-rw-r--r--javax/naming/spi/Resolver.java35
-rw-r--r--javax/naming/spi/StateFactory.java28
-rw-r--r--javax/swing/CellRendererPane.java2
-rw-r--r--javax/swing/DefaultButtonModel.java18
-rw-r--r--javax/swing/DefaultCellEditor.java19
-rw-r--r--javax/swing/DefaultDesktopManager.java11
-rw-r--r--javax/swing/JCheckBoxMenuItem.java37
-rw-r--r--javax/swing/JComboBox.java8
-rw-r--r--javax/swing/JComponent.java48
-rw-r--r--javax/swing/JEditorPane.java8
-rw-r--r--javax/swing/JFileChooser.java100
-rw-r--r--javax/swing/JFormattedTextField.java74
-rw-r--r--javax/swing/JFrame.java86
-rw-r--r--javax/swing/JLabel.java85
-rw-r--r--javax/swing/JLayeredPane.java14
-rw-r--r--javax/swing/JList.java13
-rw-r--r--javax/swing/JMenu.java273
-rw-r--r--javax/swing/JMenuItem.java109
-rw-r--r--javax/swing/JOptionPane.java95
-rw-r--r--javax/swing/JPopupMenu.java31
-rw-r--r--javax/swing/JProgressBar.java462
-rw-r--r--javax/swing/JRootPane.java1
-rw-r--r--javax/swing/JScrollPane.java8
-rw-r--r--javax/swing/JSlider.java6
-rw-r--r--javax/swing/JSpinner.java2
-rw-r--r--javax/swing/JTabbedPane.java176
-rw-r--r--javax/swing/JTable.java1424
-rw-r--r--javax/swing/JTree.java8
-rw-r--r--javax/swing/JViewport.java2
-rw-r--r--javax/swing/KeyboardManager.java3
-rw-r--r--javax/swing/ListSelectionModel.java264
-rw-r--r--javax/swing/ProgressMonitor.java21
-rw-r--r--javax/swing/RepaintManager.java145
-rw-r--r--javax/swing/SwingUtilities.java153
-rw-r--r--javax/swing/TransferHandler.java24
-rw-r--r--javax/swing/UIDefaults.java26
-rw-r--r--javax/swing/UIManager.java27
-rw-r--r--javax/swing/WindowConstants.java29
-rw-r--r--javax/swing/border/AbstractBorder.java2
-rw-r--r--javax/swing/border/BevelBorder.java2
-rw-r--r--javax/swing/border/CompoundBorder.java6
-rw-r--r--javax/swing/border/TitledBorder.java729
-rw-r--r--javax/swing/event/EventListenerList.java10
-rw-r--r--javax/swing/plaf/basic/BasicButtonUI.java9
-rw-r--r--javax/swing/plaf/basic/BasicCheckBoxUI.java25
-rw-r--r--javax/swing/plaf/basic/BasicComboBoxUI.java126
-rw-r--r--javax/swing/plaf/basic/BasicComboPopup.java10
-rw-r--r--javax/swing/plaf/basic/BasicDirectoryModel.java14
-rw-r--r--javax/swing/plaf/basic/BasicFileChooserUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicIconFactory.java10
-rw-r--r--javax/swing/plaf/basic/BasicInternalFrameUI.java185
-rw-r--r--javax/swing/plaf/basic/BasicListUI.java55
-rw-r--r--javax/swing/plaf/basic/BasicOptionPaneUI.java2
-rw-r--r--javax/swing/plaf/basic/BasicPanelUI.java64
-rw-r--r--javax/swing/plaf/basic/BasicProgressBarUI.java36
-rw-r--r--javax/swing/plaf/basic/BasicRadioButtonUI.java8
-rw-r--r--javax/swing/plaf/basic/BasicRootPaneUI.java5
-rw-r--r--javax/swing/plaf/basic/BasicScrollPaneUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicSliderUI.java65
-rw-r--r--javax/swing/plaf/basic/BasicSpinnerUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicTabbedPaneUI.java20
-rw-r--r--javax/swing/plaf/basic/BasicTableHeaderUI.java26
-rw-r--r--javax/swing/plaf/basic/BasicTableUI.java19
-rw-r--r--javax/swing/plaf/basic/BasicTextAreaUI.java4
-rw-r--r--javax/swing/plaf/basic/BasicTextUI.java13
-rw-r--r--javax/swing/plaf/basic/BasicToggleButtonUI.java37
-rw-r--r--javax/swing/plaf/basic/BasicToolBarUI.java68
-rw-r--r--javax/swing/plaf/basic/BasicTreeUI.java86
-rw-r--r--javax/swing/plaf/metal/MetalBorders.java100
-rw-r--r--javax/swing/plaf/metal/MetalButtonUI.java67
-rw-r--r--javax/swing/plaf/metal/MetalCheckBoxUI.java2
-rw-r--r--javax/swing/plaf/metal/MetalComboBoxButton.java5
-rw-r--r--javax/swing/plaf/metal/MetalComboBoxIcon.java3
-rw-r--r--javax/swing/plaf/metal/MetalFileChooserUI.java68
-rw-r--r--javax/swing/plaf/metal/MetalIconFactory.java3
-rw-r--r--javax/swing/plaf/metal/MetalInternalFrameTitlePane.java9
-rw-r--r--javax/swing/plaf/metal/MetalLookAndFeel.java12
-rw-r--r--javax/swing/plaf/metal/MetalPopupMenuSeparatorUI.java2
-rw-r--r--javax/swing/plaf/metal/MetalRadioButtonUI.java9
-rw-r--r--javax/swing/plaf/metal/MetalRootPaneUI.java2
-rw-r--r--javax/swing/plaf/metal/MetalScrollBarUI.java16
-rw-r--r--javax/swing/plaf/metal/MetalSeparatorUI.java2
-rw-r--r--javax/swing/plaf/metal/MetalSliderUI.java34
-rw-r--r--javax/swing/plaf/metal/MetalSplitPaneDivider.java5
-rw-r--r--javax/swing/plaf/metal/MetalTabbedPaneUI.java6
-rw-r--r--javax/swing/plaf/metal/MetalToolTipUI.java6
-rw-r--r--javax/swing/plaf/metal/MetalUtils.java2
-rw-r--r--javax/swing/plaf/multi/MultiComboBoxUI.java9
-rw-r--r--javax/swing/plaf/multi/MultiFileChooserUI.java18
-rw-r--r--javax/swing/plaf/multi/MultiListUI.java9
-rw-r--r--javax/swing/plaf/multi/MultiLookAndFeel.java3
-rw-r--r--javax/swing/plaf/multi/MultiOptionPaneUI.java6
-rw-r--r--javax/swing/plaf/multi/MultiSplitPaneUI.java18
-rw-r--r--javax/swing/plaf/multi/MultiTabbedPaneUI.java9
-rw-r--r--javax/swing/table/AbstractTableModel.java12
-rw-r--r--javax/swing/table/DefaultTableModel.java61
-rw-r--r--javax/swing/table/JTableHeader.java423
-rw-r--r--javax/swing/table/TableCellEditor.java28
-rw-r--r--javax/swing/table/TableCellRenderer.java30
-rw-r--r--javax/swing/text/AbstractDocument.java59
-rw-r--r--javax/swing/text/AbstractWriter.java3
-rw-r--r--javax/swing/text/DefaultCaret.java64
-rw-r--r--javax/swing/text/DefaultEditorKit.java551
-rw-r--r--javax/swing/text/FieldView.java24
-rw-r--r--javax/swing/text/GapContent.java469
-rw-r--r--javax/swing/text/JTextComponent.java31
-rw-r--r--javax/swing/text/PlainView.java233
-rw-r--r--javax/swing/text/StyleContext.java99
-rw-r--r--javax/swing/text/TextAction.java104
-rw-r--r--javax/swing/text/Utilities.java66
-rw-r--r--javax/swing/text/html/HTMLDocument.java128
-rw-r--r--javax/swing/text/html/HTMLEditorKit.java5
-rw-r--r--javax/swing/text/html/ImageView.java441
-rw-r--r--javax/swing/text/html/MinimalHTMLWriter.java452
-rw-r--r--javax/swing/tree/AbstractLayoutCache.java7
-rw-r--r--javax/swing/tree/DefaultMutableTreeNode.java15
-rw-r--r--javax/swing/tree/DefaultTreeCellRenderer.java442
-rw-r--r--javax/swing/tree/DefaultTreeModel.java6
-rw-r--r--javax/swing/tree/DefaultTreeSelectionModel.java20
-rw-r--r--javax/swing/tree/ExpandVetoException.java71
-rw-r--r--javax/swing/tree/FixedHeightLayoutCache.java6
-rw-r--r--javax/swing/tree/RowMapper.java20
-rw-r--r--javax/swing/tree/TreeNode.java3
-rw-r--r--javax/swing/tree/TreeSelectionModel.java102
-rw-r--r--javax/swing/tree/VariableHeightLayoutCache.java6
-rw-r--r--native/Makefile.am8
-rw-r--r--native/jawt/Makefile.am14
-rw-r--r--native/jni/classpath/jcl.h6
-rw-r--r--native/jni/gtk-peer/Makefile.am24
-rw-r--r--native/jni/gtk-peer/cairographics2d.h119
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c699
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c311
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphics.c243
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphicsCopy.c132
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c108
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c758
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c2018
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c154
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.c14
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c9
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c49
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c5
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c348
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c4
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkVolatileImage.c190
-rw-r--r--native/jni/gtk-peer/gtkpeer.h44
-rw-r--r--native/jni/java-net/Makefile.am4
-rw-r--r--native/jni/java-net/java_net_VMURLConnection.c102
-rw-r--r--native/jni/java-net/javanet.c3
-rw-r--r--native/jni/java-nio/Makefile.am1
-rw-r--r--native/jni/java-nio/gnu_java_nio_VMChannel.c525
-rw-r--r--native/jni/midi-dssi/dssi_data.h7
-rw-r--r--native/jni/native-lib/cpproc.h2
-rw-r--r--native/jni/qt-peer/eventmethods.h6
-rw-r--r--native/jni/qt-peer/qtmenupeer.cpp47
-rw-r--r--native/plugin/.cvsignore6
-rw-r--r--native/plugin/Makefile.am19
-rw-r--r--native/plugin/gcjwebplugin.cc1745
-rw-r--r--resource/gnu/classpath/tools/appletviewer/MessagesBundle.properties93
-rw-r--r--resource/gnu/classpath/tools/appletviewer/MessagesBundle_de.properties74
-rw-r--r--resource/gnu/classpath/tools/getopt/Messages.properties49
-rw-r--r--resource/gnu/classpath/tools/jar/messages.properties71
-rw-r--r--resource/gnu/classpath/tools/jarsigner/MessageBundle.properties33
-rw-r--r--resource/gnu/classpath/tools/jarsigner/messages.properties122
-rw-r--r--resource/gnu/classpath/tools/keytool/MessageBundle.properties95
-rw-r--r--resource/gnu/classpath/tools/keytool/messages.properties542
-rw-r--r--resource/gnu/classpath/tools/native2ascii/messages.properties43
-rw-r--r--resource/gnu/classpath/tools/serialver/messages.properties44
-rwxr-xr-xscripts/check_jni_methods.sh2
-rw-r--r--tools/.cvsignore1
-rwxr-xr-xtools/Makefile.am53
-rw-r--r--tools/appletviewer.in19
-rw-r--r--tools/gnu/classpath/tools/appletviewer/AppletTag.java22
-rw-r--r--tools/gnu/classpath/tools/appletviewer/Main.java180
-rw-r--r--tools/gnu/classpath/tools/getopt/ClasspathToolParser.java16
-rw-r--r--tools/gnu/classpath/tools/getopt/FileArgumentCallback.java3
-rw-r--r--tools/gnu/classpath/tools/getopt/Messages.java67
-rw-r--r--tools/gnu/classpath/tools/getopt/Option.java1
-rw-r--r--tools/gnu/classpath/tools/getopt/OptionGroup.java150
-rw-r--r--tools/gnu/classpath/tools/getopt/Parser.java176
-rw-r--r--tools/gnu/classpath/tools/giop/GRMIC.java23
-rw-r--r--tools/gnu/classpath/tools/giop/GRMIC.txt24
-rw-r--r--tools/gnu/classpath/tools/giop/grmic/GiopRmicCompiler.java94
-rw-r--r--tools/gnu/classpath/tools/jar/Action.java3
-rw-r--r--tools/gnu/classpath/tools/jar/Creator.java89
-rw-r--r--tools/gnu/classpath/tools/jar/Extractor.java53
-rw-r--r--tools/gnu/classpath/tools/jar/Indexer.java144
-rw-r--r--tools/gnu/classpath/tools/jar/Lister.java48
-rw-r--r--tools/gnu/classpath/tools/jar/Main.java133
-rw-r--r--tools/gnu/classpath/tools/jar/Messages.java67
-rw-r--r--tools/gnu/classpath/tools/jar/Updater.java44
-rw-r--r--tools/gnu/classpath/tools/jar/WorkSet.java86
-rw-r--r--tools/gnu/classpath/tools/jarsigner/JarSigner.java2
-rw-r--r--tools/gnu/classpath/tools/jarsigner/Main.java269
-rw-r--r--tools/gnu/classpath/tools/jarsigner/Messages.java4
-rw-r--r--tools/gnu/classpath/tools/jarsigner/jarsigner.txt116
-rw-r--r--tools/gnu/classpath/tools/keytool/CertReqCmd.java169
-rw-r--r--tools/gnu/classpath/tools/keytool/Command.java63
-rw-r--r--tools/gnu/classpath/tools/keytool/DeleteCmd.java116
-rw-r--r--tools/gnu/classpath/tools/keytool/ExportCmd.java170
-rw-r--r--tools/gnu/classpath/tools/keytool/GenKeyCmd.java199
-rw-r--r--tools/gnu/classpath/tools/keytool/IdentityDBCmd.java128
-rw-r--r--tools/gnu/classpath/tools/keytool/ImportCmd.java333
-rw-r--r--tools/gnu/classpath/tools/keytool/KeyCloneCmd.java162
-rw-r--r--tools/gnu/classpath/tools/keytool/KeyPasswdCmd.java143
-rw-r--r--tools/gnu/classpath/tools/keytool/ListCmd.java132
-rw-r--r--tools/gnu/classpath/tools/keytool/Main.java231
-rw-r--r--tools/gnu/classpath/tools/keytool/Messages.java4
-rw-r--r--tools/gnu/classpath/tools/keytool/PrintCertCmd.java73
-rw-r--r--tools/gnu/classpath/tools/keytool/SelfCertCmd.java196
-rw-r--r--tools/gnu/classpath/tools/keytool/StorePasswdCmd.java116
-rw-r--r--tools/gnu/classpath/tools/keytool/keytool.txt616
-rw-r--r--tools/gnu/classpath/tools/native2ascii/Messages.java67
-rw-r--r--tools/gnu/classpath/tools/native2ascii/Native2ASCII.java185
-rw-r--r--tools/gnu/classpath/tools/rmi/RMIC.java25
-rw-r--r--tools/gnu/classpath/tools/rmi/RMIC.txt36
-rw-r--r--tools/gnu/classpath/tools/serialver/Messages.java68
-rw-r--r--tools/gnu/classpath/tools/serialver/SerialVer.java163
-rw-r--r--tools/jarsigner.in18
-rw-r--r--tools/keytool.in18
-rw-r--r--tools/toolwrapper.c (renamed from tools/appletviewer.c)51
-rw-r--r--vm/reference/gnu/java/nio/VMChannel.java197
-rw-r--r--vm/reference/java/lang/VMClassLoader.java8
-rw-r--r--vm/reference/java/net/VMURLConnection.java79
469 files changed, 36638 insertions, 12976 deletions
diff --git a/.externalToolBuilders/Configure.launch b/.externalToolBuilders/Configure.launch
index 96bcda0fe..d2347ae84 100644
--- a/.externalToolBuilders/Configure.launch
+++ b/.externalToolBuilders/Configure.launch
@@ -1,2 +1,13 @@
-<?xml version='1.0'?>
-<launchConfiguration type='org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType'><stringAttribute key='org.eclipse.debug.core.ATTR_REFRESH_SCOPE' value='${project}'/><stringAttribute key='org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS' value='full,incremental,auto,'/><stringAttribute key='org.eclipse.ui.externaltools.ATTR_BUILD_SCOPE' value='${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;launchConfigurationWorkingSet factoryID=&quot;org.eclipse.ui.internal.WorkingSetFactory&quot; name=&quot;workingSet&quot; editPageId=&quot;org.eclipse.ui.resourceWorkingSetPage&quot;&gt;&#10;&lt;item factoryID=&quot;org.eclipse.ui.internal.model.ResourceFactory&quot; path=&quot;/classpath/Makefile.in&quot; type=&quot;1&quot;/&gt;&#10;&lt;/launchConfigurationWorkingSet&gt;}'/><stringAttribute key='org.eclipse.ui.externaltools.ATTR_LOCATION' value='${build_project}/configure'/><booleanAttribute key='org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED' value='true'/><stringAttribute key='org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY' value='${build_project}'/><booleanAttribute key='org.eclipse.ui.externaltools.ATTR_BUILDER_ENABLED' value='true'/><stringAttribute key='org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS' value='--prefix=${build_project}/install --enable-regen-headers --enable-gtk-cairo'/><booleanAttribute key='org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND' value='false'/><booleanAttribute key='org.eclipse.debug.core.appendEnvironmentVariables' value='true'/></launchConfiguration> \ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?>
+<launchConfiguration type="org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType">
+<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_BUILDER_ENABLED" value="true"/>
+<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_BUILD_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;launchConfigurationWorkingSet editPageId=&quot;org.eclipse.ui.resourceWorkingSetPage&quot; factoryID=&quot;org.eclipse.ui.internal.WorkingSetFactory&quot; name=&quot;workingSet&quot;&gt;&#10;&lt;item factoryID=&quot;org.eclipse.ui.internal.model.ResourceFactory&quot; path=&quot;/classpath/Makefile.in&quot; type=&quot;1&quot;/&gt;&#10;&lt;/launchConfigurationWorkingSet&gt;}"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="--prefix=${build_project}/install --enable-regen-headers --with-ecj"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,auto,"/>
+<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${project}"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${build_project}"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${build_project}/configure"/>
+<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
+<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
+</launchConfiguration>
diff --git a/ChangeLog b/ChangeLog
index b63b3cbb3..2153a188d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,3398 @@
+2006-06-05 Tania Bento <tbento@redhat.com>
+
+ * javax/swing/JFrame.java
+ (frameInit): Set background color and fixed layout parameters.
+
+2006-06-05 Tom Tromey <tromey@redhat.com>
+
+ * NEWS: Mention VMURLConnection.
+
+2006-06-05 Lillian Angel <langel@redhat.com>
+
+ * native/plugin/gcjwebplugin.cc:
+ Added new field to keep track of initialization.
+ (plugin_start_appletviewer): Fixed to return an error value, if
+ an error was encountered when loading the appletviewer.
+ (GCJ_NEW): Added call to plugin_failed if the loading of the appletviewer
+ has failed.
+ (plugin_failed): New helper function. Shows a warning if the appletviewer
+ has not been installed.
+ (NP_Initialize): Added code to make sure this function is only called
+ once.
+
+2006-06-05 Lillian Angel <langel@redhat.com>
+
+ * native/plugin/Makefile.am:
+ Fixed to use a set plugin directory in the .mozilla directory.
+ All applet logs are now stored here, instead of /tmp.
+ * native/plugin/gcjwebplugin.cc:
+ Added new fields for security warning.
+ (GCJ_NEW): Added code to generate a security warning for all pages
+ that spawn an appletviewer. This warning asks the user if they trust
+ the applet and if they would like to add it to a 'whitelist'. This
+ whitelist keeps track of all the addresses the user would like
+ to trust indefinitely.
+ (plugin_user_trusts_documentbase): New helper function.
+ (plugin_add_documentbase_to_whitelist): New helper function.
+ (plugin_ask_user_about_documentbase): New helper function.
+ (plugin_in_pipe_callback): Fixed check to determine if channel_error
+ has been set.
+ (plugin_start_appletviewer): Likewise.
+ (plugin_create_applet_tag): Reset all fields to null after they have been
+ freed.
+ (plugin_send_message_to_appletviewer): Fixed all error checks to determine
+ if channel_error has been set.
+ (plugin_stop_appletviewer): Likewise.
+ (NP_Initialize): Likewise. Also, added code to determine if directory and file
+ should be created.
+
+2006-06-05 Francis Kung <fkung@redhat.com>
+
+ PR 27507
+ * gnu/java/awt/peer/gtk/GtkImage.java
+ (getSource): Added check to determine if in
+ errorLoading state.
+ * gnu/java/awt/peer/gtk/GtkToolkit.java
+ (createImage): Added check to prevent NPE.
+
+2006-06-05 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/text/html/HTMLEditorKit.java (HTMLFactory.create):
+ Create the ImageView, when applicable.
+ * gnu/javax/swing/text/html/CombinedAttributes.java,
+ javax/swing/text/html/ImageView.java: New files.
+
+2006-06-05 Roman Kennke <kennke@aicas.com>
+
+ PR 27834
+ * javax/swing/text/GapContent.java
+ (setPositionsInRange): Compare with startIndex and endIndex
+ rather than start and end.
+ (dumpMarks): Only dump real marks.
+
+2006-06-05 Sven de Marothy <sven@physto.se>
+
+ * gnu/java/awt/peer/gtk/ComponentGraphics.java
+ (ComponentGraphics): Use 0,0 as clip origin.
+
+2006-06-04 Andrew John Hughes <gnu_andrew@member.fsf.org>
+
+ * java/util/Formattable.java,
+ * java/util/FormattableFlags.java,
+ * java/util/Formatter.java:
+ Documented.
+
+2006-03-20 Andrew John Hughes <gnu_andrew@member.fsf.org>
+
+ * java/util/Formatter.java:
+ Make the class final.
+
+2005-09-26 Tom Tromey <tromey@redhat.com>
+
+ * java/util/Formatter.java (format): Set fmtLocale.
+ (applyLocalization): New method.
+ (basicIntegralConversion): Likewise.
+ (hexOrOctalConversion): Use it.
+ (decimalConversion): New method.
+ (format): Use decimalConversion, dateTimeConversion.
+ (genericFormat): Upper-case earlier. Justify correctly.
+ (singleDateTimeConversion): New method.
+ (dateTimeConversion): Likewise.
+
+2005-09-25 Tom Tromey <tromey@redhat.com>
+
+ * java/util/Formatter.java (lineSeparator): Use SystemProperties.
+
+2005-09-24 Tom Tromey <tromey@redhat.com>
+
+ * java/util/FormattableFlags.java (PLUS, SPACE, ZERO, COMMA,
+ PAREN): New constants.
+ * java/util/Formattable.java: New file.
+ * java/util/Formatter.java: New file.
+
+2005-08-13 Tom Tromey <tromey@redhat.com>
+
+ * java/util/FormattableFlags.java: New file.
+
+2006-06-04 Sven de Marothy <sven@physto.se>
+
+ * gnu/java/awt/peer/gtk/GtkComponentPeer.java
+ (createVolatileImage): Pass peer to VolatileImage constructor.
+ * java/awt/Component.java
+ (createVolatileImage): Call peer method directly.
+
+2006-06-04 Andrew John Hughes <gnu_andrew@member.fsf.org>
+
+ * java/util/DuplicateFormatFlagsException.java,
+ * java/util/FormatFlagsConversionMismatchException.java,
+ * java/util/FormatterClosedException.java,
+ * java/util/IllegalFormatCodePointException.java,
+ * java/util/IllegalFormatConversionException.java,
+ * java/util/IllegalFormatException.java,
+ * java/util/IllegalFormatFlagsException.java,
+ * java/util/IllegalFormatPrecisionException.java,
+ * java/util/IllegalFormatWidthException.java,
+ * java/util/MissingFormatArgumentException.java,
+ * java/util/MissingFormatWidthException.java,
+ * java/util/UnknownFormatConversionException.java,
+ * java/util/UnknownFormatFlagsException.java:
+ Documented.
+
+2005-08-13 Tom Tromey <tromey@redhat.com>
+
+ * java/util/UnknownFormatConversionException.java
+ (serialVersionUID): New field.
+ (s): Renamed from 'conv' for serialization.
+ * java/util/MissingFormatWidthException.java (serialVersionUID):
+ New field.
+ (s): Renamed from 'width' for serialization.
+ * java/util/MissingFormatArgumentException.java
+ (serialVersionUID): New field.
+ (s): Renamed from 'spec' for serialization.
+ * java/util/IllegalFormatWidthException.java (serialVersionUID):
+ New field.
+ (w): Renamed from 'width' for serialization.
+ * java/util/IllegalFormatPrecisionException.java
+ (serialVersionUID): New field.
+ (p): Renamed from 'precision' for serialization.
+ * java/util/IllegalFormatFlagsException.java (serialVersionUID):
+ New field.
+ * java/util/IllegalFormatConversionException.java
+ (serialVersionUID): New field.
+ (c): Renamed from 'conv' for serialization.
+ (arg): Renamed from 'argClass' for serialization.
+ * java/util/IllegalFormatCodePointException.java
+ (serialVersionUID): New field.
+ (c): Renamed from 'codepoint' for serialization.
+ * java/util/FormatFlagsConversionMismatchException.java
+ (serialVersionUID): New field.
+ (f): Renamed from 'flags' for serialization.
+ (c): Renamed from 'conversion' for serialization.
+ * java/util/DuplicateFormatFlagsException.java (serialVersionUID):
+ New field.
+ * java/util/IllegalFormatException.java (serialVersionUID): New
+ field.
+ * java/util/FormatterClosedException.java (serialVersionUID): New
+ field.
+
+2005-04-20 Tom Tromey <tromey@redhat.com>
+
+ * java/util/DuplicateFormatFlagsException.java: New file.
+ * java/util/FormatFlagsConversionMismatchException.java: New file.
+ * java/util/FormatterClosedException.java: New file.
+ * java/util/IllegalFormatCodePointException.java: New file.
+ * java/util/IllegalFormatConversionException.java: New file.
+ * java/util/UnknownFormatFlagsException.java: New file.
+ * java/util/UnknownFormatConversionException.java: New file.
+ * java/util/MissingFormatWidthException.java: New file.
+ * java/util/MissingFormatArgumentException.java: New file.
+ * java/util/IllegalFormatWidthException.java: New file.
+ * java/util/IllegalFormatPrecisionException.java: New file.
+ * java/util/IllegalFormatFlagsException.java: New file.
+ * java/util/IllegalFormatException.java: New file.
+
+2006-06-04 Sven de Marothy <sven@physto.se>
+
+ * gnu/java/awt/peer/gtk/CairoSurface.java
+ (getFlippedBuffer): New method.
+ (getGtkImage): Renamed method.
+ * gnu/java/awt/peer/gtk/ComponentGraphicsCopy.java
+ * gnu/java/awt/peer/gtk/GtkVolatileImage.java
+ Renamed getSharedImage to getGtkImage.
+ * include/gnu_java_awt_peer_gtk_CairoSurface.h
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c
+ (getFlippedBuffer): New method
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphics.c
+ Avoid window casts.
+
+2006-03-20 Andrew John Hughes <gnu_andrew@member.fsf.org>
+
+ * java/lang/System.java:
+ (nanoTime()): Documented.
+
+2006-03-20 Tom Tromey <tromey@redhat.com>
+
+ * java/lang/System.java:
+ (nanoTime()): Implemented.
+
+2006-03-01 Anthony Balkissoon <abalkiss@redhat.com>
+
+ * java/math/BigDecimal.java:
+ (precision): Fixed overflow problem with large numbers.
+ (longValueExact): New method.
+ (intValueExact): Likewise.
+ (byteValueExact): Likewise.
+ (shortValueExact): Likewise.
+
+2006-03-01 Anthony Balkissoon <abalkiss@redhat.com>
+
+ * java/math/BigDecimal.java:
+ (remainder(BigDecimal)): New method.
+ (divideAndRemainder(BigDecimal)): Likewise.
+ (divideToIntegralValue(BigDecimal)): Likewise.
+ (floor): New implementation method.
+
+2006-02-28 Anthony Balkissoon <abalkiss@redhat.com>
+
+ * java/math/BigDecimal.java:
+ (divide(BigDecimal, int, RoundingMode)): New method.
+ (divide(BigDecimal, RoundingMode)): Likewise.
+ (divide(BigDecimal, int, int)): Removed incorrect throwing of exception
+ when the new scale is < 0.
+ (setScale(int, RoundingMode)): New method.
+ (ulp): Likewise.
+
+2006-02-27 Anthony Balkissoon <abalkiss@redhat.com>
+
+ * java/math/BigDecimal.java: Replaced occurences of BigInteger.valueOf
+ with BigInteger.ZERO, BigInteger.ONE, BigInteger.TEN where appropriate.
+ (add(BigDecimal, MathContext)): New method.
+ (subtract(BigDecimal, MathContext)): Likewise.
+ (precision): Fixed to correctly handle BigIntegers with more than 19
+ digits.
+ (pow(int, MathContext)): New method.
+
+2006-02-27 Anthony Balkissoon <abalkiss@redhat.com>
+
+ * java/math/BigDecimal.java: Added @throws clause to constructors.
+ (mathContext): Removed this unneeded field.
+ (BigDecimal(int, MathContext)): New constructor.
+ (BigDecimal(BigInteger, int, MathContext)): Likewise.
+ (multiply(BigDecimal, MathContext)): New method.
+ (negate(MathContext)): Likewise.
+ (plus(MathContext)): Likewise.
+ (numDigitsInLong): Fixed to properly handle negatives.
+
+2006-02-24 Anthony Balkissoon <abalkiss@redhat.com>
+
+ * java/math/BigDecimal.java:
+ (BigDecimal(long, MathContext)): New constructor.
+ (BigDecimal(BigInteger, MathContext)): Likewise.
+ (BigDecimal(String, MathContext)): Likewise.
+ (BigDecimal(double, MathContext)): Likewise.
+ (round): Fixed a typo where the precision field was used instead of a
+ call to the precision method, and also store the new precision in the
+ returned BigDecimal.
+ (abs(MathContext)): New method.
+
+2006-02-24 Anthony Balkissoon <abalkiss@redhat.com>
+
+ * java/math/BigDecimal.java
+ (toBigInteger): Fixed problem where this method couldn't handle
+ negative values for scale.
+ (toBigIntegerExact): New method.
+ (stripTrailingZeros): Likewise.
+
+2006-02-23 Anthony Balkissoon <abalkiss@redhat.com>
+
+ * java/math/BigDecimal.java:
+ (toString): Fixed a problem where the negative sign was being displayed
+ twice in the exponent.
+ (toEngineeringString): New method.
+ (toPlainString): Likewise.
+ (pow): Likewise.
+
+2006-02-23 Anthony Balkissoon <abalkiss@redhat.com>
+
+ * java/math/BigDecimal.java:
+ (toString): Rewrote this method to behave as specified. Added API
+ comments to explain behaviour.
+ (scaleByPowerOfTen): New method.
+
+2006-02-22 Anthony Balkissoon <abalkiss@redhat.com>
+
+ * java/math/BigDecimal.java:
+ (BigDecimal(char[], int, int, MathContext)): New constructor.
+ (BigDecimal(char[], MathContext)): Likewise.
+ (BigDecimal(char[])): Likewise.
+ (BigDecimal(char[], int, int)): Likewise.
+ (BigDecimal(String)): Fixed handling of exponent and scale.
+
+2006-02-21 Anthony Balkissoon <abalkiss@redhat.com>
+
+ * java/math/BigDecimal.java:
+ (mathContext): New field.
+ (precision): Likewise.
+ (BigDecimal(int)): New constructor.
+ (BigDecimal(long)): Likewise.
+ (BigDecimal(BigInteger)): Added API docs.
+ (BigDecimal(BigInteger, int)): Removed incorrect NumberFormatException
+ and added API docs.
+ (plus): New method.
+ (round): Likewise.
+ (precision): Likewise.
+ (valueOf): Likewise.
+ (numDigitsInLong): New implementation method.
+
+2006-02-21 Anthony Balkissoon <abalkiss@redhat.com>
+
+ * java/math/MathContext.java: New class.
+
+2006-06-04 Andrew John Hughes <gnu_andrew@member.fsf.org>
+
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphics.c:
+ (drawVolatile): Add casts.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c:
+ (getOutline): Add casts.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkVolatileImage.c:
+ Comment out unused prototype.
+ (getPixels): Add appropriate cast and comment out unused variable.
+
+2006-06-04 Raif S. Naffah <raif@swiftdsl.com.au>
+
+ * gnu/javax/crypto/sasl/SaslUtil.java: Remove unused import.
+ * gnu/javax/crypto/sasl/srp/SRPRegistry.java (PASSWORD_DB): Fix javadoc @link.
+ * gnu/javax/crypto/sasl/srp/PasswordFile.java: Removed unused import.
+ * gnu/javax/crypto/prng/CSPRNG.java (FILE_SOURCES): Fix javadoc @see.
+ (getSystemInstance): Fix javadoc @link.
+ (counter): Increased visibility.
+ * gnu/javax/crypto/pad/TLS1.java: Remove unused import.
+ * gnu/javax/crypto/pad/IPad.java: Fix javadoc @link.
+ * gnu/javax/crypto/pad/PKCS1_V1_5.java (PKCS1_V1_5): Likewise.
+ * gnu/javax/crypto/pad/PKCS7.java (PKCS7): Likewise.
+ * gnu/javax/crypto/pad/TBC.java (TBC): Likewise.
+ * gnu/javax/crypto/mode/CTR.java: Remove unused import.
+ * gnu/javax/crypto/mode/BaseMode.java (defaultBlockSize): Fix javadoc @see.
+ * gnu/javax/crypto/key/dh/GnuDHPrivateKey.java (getEncoded): Fix javadoc @see.
+ * gnu/javax/crypto/jce/spec/TMMHParameterSpec.java: Fix javadoc @link.
+ * gnu/javax/crypto/keyring/AuthenticatedEntry.java: Remove unused imports.
+ * gnu/javax/crypto/keyring/CertificateEntry.java: Likewise.
+ * gnu/javax/crypto/keyring/CertPathEntry.java: Likewise.
+ * gnu/javax/crypto/keyring/EncryptedEntry.java: Likewise.
+ * gnu/javax/crypto/keyring/PublicKeyEntry.java: Likewise.
+ * gnu/javax/crypto/mac/OMAC.java: Likewise.
+ * gnu/javax/crypto/jce/key/AnubisSecretKeyFactoryImpl.java: Likewise.
+ * gnu/javax/crypto/jce/key/BlowfishSecretKeyFactoryImpl.java: Likewise.
+ * gnu/javax/crypto/jce/key/Cast5SecretKeyFactoryImpl.java: Likewise.
+ * gnu/javax/crypto/jce/key/KhazadSecretKeyFactoryImpl.java: Likewise.
+ * gnu/javax/crypto/jce/key/RijndaelSecretKeyFactoryImpl.java: Likewise.
+ * gnu/javax/crypto/jce/key/SerpentSecretKeyFactoryImpl.java: Likewise.
+ * gnu/javax/crypto/jce/key/SquareSecretKeyFactoryImpl.java: Likewise.
+ * gnu/javax/crypto/jce/key/TwofishSecretKeyFactoryImpl.java: Likewise.
+ * gnu/javax/crypto/jce/mac/OMacImpl.java: Likewise.
+ * gnu/javax/crypto/jce/prng/CSPRNGSpi.java: Likewise.
+ * gnu/javax/crypto/cipher/IBlockCipherSpi.java: Fix javadoc @link.
+ * gnu/javax/crypto/jce/cipher/CipherAdapter.java (CipherAdapter): Likewise.
+ * gnu/javax/crypto/cipher/BaseCipher.java: Remove unused import.
+ * gnu/javax/crypto/assembly/Cascade.java: Fix javadoc @link.
+ * gnu/javax/crypto/assembly/Direction.java: Likewise.
+ * gnu/javax/crypto/assembly/Transformer.java: Likewise.
+
+2006-06-04 Raif S. Naffah <raif@swiftdsl.com.au>
+
+ * gnu/java/security/PolicyFile.java: Updated copyright year.
+ (logger): Increased visibility.
+ * gnu/java/security/x509/Util.java: Updated copyright year.
+ (hexDump): Fix javadoc @link.
+ * gnu/java/security/x509/ext/GeneralNames.java: Updated copyright year.
+ Removed unused import.
+ * gnu/java/security/sig/rsa/RSAPSSSignatureRawCodec.java: Fix javadoc @link.
+ * gnu/java/security/sig/ISignature.java (SOURCE_OF_RANDOMNESS): Likewise.
+ * gnu/java/security/util/ExpirableObject.java: Likewise.
+ (destroy): Likewise.
+ * gnu/java/security/util/SimpleList.java (SimpleList): Likewise.
+ * gnu/java/security/provider/PKIXCertPathValidatorImpl.java:
+ Updated copyright year.
+ (checkCRL): Fix javadoc @param.
+
+2006-06-03 Andrew John Hughes <gnu_andrew@member.fsf.org>
+
+ * java/lang/annotation/IncompleteAnnotationException.java:
+ Documented.
+
+2004-08-07 Tom Tromey <tromey@redhat.com>
+
+ * java/lang/annotation/IncompleteAnnotationException.java: New
+ file.
+
+2006-06-02 Sven de Marothy <sven@physto.se>
+
+ * gnu/java/awt/peer/gtk/CairoGraphics2D.java
+ (cairoPreserveClip, cairoResetClip): New methods.
+ (setClip, clip): Reimplement.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c
+ * include/gnu_java_awt_peer_gtk_CairoGraphics2D.h
+ (cairoPreserveClip, cairoResetClip): New methods.
+
+2006-06-02 Sven de Marothy <sven@physto.se>
+
+ * gnu/java/awt/peer/gtk/VolatileImageGraphics.java
+ * include/gnu_java_awt_peer_gtk_GtkVolatileImage.h
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkVolatileImage.c
+ New files.
+ * gnu/java/awt/peer/gtk/ComponentGraphics.java
+ (drawImage): Overloads for VolatileImage drawing.
+ (drawVolatile): New method.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphics.c
+ * include/gnu_java_awt_peer_gtk_ComponentGraphics.h
+ (drawVolatile): New method.
+ * gnu/java/awt/peer/gtk/GtkVolatileImage.java
+ Unstub implementation.
+ * include/Makefile.am
+ * native/jni/gtk-peer/Makefile.am
+ Add new files.
+ * native/jni/gtk-peer/gtkpeer.h
+ New prototype.
+
+2006-06-03 Roman Kennke <kennke@aicas.com>
+
+ PR 27418
+ * javax/swing/plaf/basic/BasicTextUI.java
+ (damageRange): Added null check to avoid NPE.
+
+2006-06-03 Roman Kennke <kennke@aicas.com>
+
+ * javax/swing/text/PlainView.java
+ (updateDamage): Check for valid longestLine and initialize if
+ necessary.
+
+2006-06-03 Mark Wielaard <mark@klomp.org>
+
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c: Use C
+ comments, not C++.
+
+2006-06-02 Sven de Marothy <sven@physto.se>
+
+ PR 27879
+ * gnu/java/awt/peer/gtk/CairoGraphics2D.java
+ (copyArea): Implement.
+ (copyAreaImpl, getRealBounds): New methods.
+ * gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java
+ * gnu/java/awt/peer/gtk/ComponentGraphics.java
+ * gnu/java/awt/peer/gtk/BufferedImageGraphics.java
+ (copyAreaImpl, getRealBounds): Implement.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c
+ (nativeCopyArea): Reimplement.
+
+2006-06-02 Andreas Tobler <a.tobler@schweiz.ch>
+
+ * configure.ac: Add -lX11 and -lXtst to XTEST_LIBS.
+ (XTEST_LIBS): New, substitute.
+ * native/jni/gtk-peer/Makefile.am (AM_LDFLAGS): Add XTEST_LIBS.
+
+2006-06-02 Roman Kennke <kennke@aicas.com>
+
+ PR 26738
+ * javax/swing/text/PlainView.java
+ (updateDamage): Rewritten for correct repainting and revalidating.
+ (findLongestLine): New helper method.
+ (getLineLength): New helper method.
+
+2006-06-02 Sven de Marothy <sven@physto.se>
+
+ * gnu/java/awt/peer/gtk/BufferedImageGraphics.java
+ * gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c
+ (nativeCopyArea): Change stride parameter to use # of ints.
+ (setPixels): Add checks.
+ * gnu/java/awt/peer/gtk/ComponentGraphics.java
+ (ComponentGraphics): Set background, clip.
+ * gnu/java/awt/peer/gtk/CairoGraphics2D.java
+ (Cairographics2D): Don't set clip.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphics.c
+ Add flush.
+
+2006-06-02 Lillian Angel <langel@redhat.com>
+
+ PR 24458
+ * java/awt/DefaultKeyboardFocusManager.java
+ (dispatchEvent): Fixed to getFocusOwner, if that fails it tries
+ to get the focused window.
+
+2006-06-01 Miriam Schuster <schmir11@web.de>
+
+ * Makefile.am: Add fallback if "mozilla-plugin" is not available.
+ Fallbacks used: "firefox-plugin" and "xulrunner-plugin".
+
+2006-06-02 Roman Kennke <kennke@aicas.com>
+
+ * javax/swing/JTable.java
+ (columnSelectionChanged): Don't return when there's only one
+ column (might still need repainting). Correctly calculate
+ repaint rectangle.
+ (valueChanged): Use return value of SwingUtilities.computeUnion
+ as dirty region.
+
+2006-06-01 Keith Seitz <keiths@redhat.com>
+
+ From Martin Platter <motse@complang.tuwien.ac.at>:
+ * gnu/classpath/jdwp/processor/EventRequestCommandSet.java
+ (executeSet): Fix buffer underflow reading reference ID.
+ * gnu/classpath/jdwp/processor/ThreadGroupReferenceCommandSet.java
+ (executeParent): Fix NPE if ThreadGroup is top-level ThreadGroup.
+ * gnu/classpath/jdwp/processor/ClassTypeCommandSet.java
+ (executeSuperclass): Handle case of Object with ID zero.
+
+2006-06-02 Raif S. Naffah <raif@swiftdsl.com.au>
+
+ * tools/gnu/classpath/tools/keytool/StorePasswdCmd.java: Fixed typo.
+ * tools/gnu/classpath/tools/keytool/CertReqCmd.java: Likewise.
+ * tools/gnu/classpath/tools/keytool/DeleteCmd.java: Likewise.
+ * tools/gnu/classpath/tools/keytool/ExportCmd.java: Likewise.
+ * tools/gnu/classpath/tools/keytool/GenKeyCmd.java: Likewise.
+ * tools/gnu/classpath/tools/keytool/IdentityDBCmd.java: Likewise.
+ * tools/gnu/classpath/tools/keytool/ImportCmd.java: Likewise.
+ * tools/gnu/classpath/tools/keytool/KeyCloneCmd.java: Likewise.
+ * tools/gnu/classpath/tools/keytool/KeyPasswdCmd.java: Likewise.
+ * tools/gnu/classpath/tools/keytool/ListCmd.java: Likewise.
+ * tools/gnu/classpath/tools/keytool/SelfCertCmd.java: Likewise.
+
+2006-06-02 Raif S. Naffah <raif@swiftdsl.com.au>
+
+ * tools/gnu/classpath/tools/keytool/Command.java (shutdownThread): New field.
+ (Command): Add the shutdown hook.
+ (doCommand): Remove the shutdown hook.
+ (ShutdownHook): New class.
+
+2006-06-02 Raif S. Naffah <raif@swiftdsl.com.au>
+
+ * tools/jarsigner.in: Use @VM_BINARY@.
+ * tools/keytool.in: Likewise.
+
+2006-06-01 Sven de Marothy <sven@physto.se>
+
+ * gnu/java/awt/peer/gtk/CairoGraphics2D.java:
+ (setColor): Update the cairo paint.
+
+2006-06-01 Mark Wielaard <mark@klomp.org>
+
+ * java/util/logging/LogManager.java (createInstance): Always add
+ original exception on warning.
+
+2006-06-01 Lillian Angel <langel@redhat.com>
+
+ * tools/gnu/classpath/tools/appletviewer/AppletTag.java
+ (prependCodebase): Fixed check. No dirname was ever considered to
+ be a file, so every applet fell into the if-statement causing a lot
+ of classloading problems with the applets.
+
+2006-06-01 Sven de Marothy <sven@physto.se>
+
+ Patch submitted by Boris Dusek.
+ * native/jni/qt-peer/qtmenupeer.cpp
+ Fix segfault
+
+2006-06-01 Roman Kennke <kennke@aicas.com>
+
+ * javax/swing/JTable.java
+ (AccessibleJTableCell.getAccessibleRow): Added comment explaining
+ why the behaviour is like it is.
+ (AccessibleJTableCell.getAccessibleStateSet): Implemented.
+ (AccessibleJTableHeader): New inner class.
+ (AccessibleJTableHeaderCell): New inner class.
+ (AccessibleJTable.lastSelectedRow): New field.
+ (AccessibleJTable.lastSelectedColumn): New field.
+ (AccessibleJTable.caption): New field.
+ (AccessibleJTable.summary): New field.
+ (AccessibleJTable.rowDescriptions): New field.
+ (AccessibleJTable.columnDescriptions): New field.
+ (AccessibleJTable): Initialize lastSelectedRow and lastSelectedColumn.
+ (AccessibleJTable.getAccessibleSelection(int)): Implemented.
+ (AccessibleJTable.isAccessibleChildSelected): Implemented.
+ (AccessibleJTable.addAccessibleSelection): Implemented.
+ (AccessibleJTable.removeAccessibleSelection): Implemented.
+ (AccessibleJTable.clearAccessibleSelection): Implemented.
+ (AccessibleJTable.selectAllAccessibleSelection): Implemented.
+ (AccessibleJTable.valueChange): Implemented.
+ (AccessibleJTable.tableRowsInserted): Implemented.
+ (AccessibleJTable.tableRowsDeleted): Implemented.
+ (AccessibleJTable.handleRowChange): New helper method.
+ (AccessibleJTable.columnAdded): Implemented.
+ (AccessibleJTable.columnMarginChanged): Implemented.
+ (AccessibleJTable.columnMoved): Implemented.
+ (AccessibleJTable.columnRemoved): Implemented.
+ (AccessibleJTable.columnSelectionChanged): Implemented.
+ (AccessibleJTable.handleColumnChange): New helper method.
+ (AccessibleJTable.editingCanceled): Implemented.
+ (AccessibleJTable.editingStopped): Implemented.
+ (AccessibleJTable.getAccessibleRow): Implemented.
+ (AccessibleJTable.getAccessibleColumn): Implemented.
+ (AccessibleJTable.getAccessibleIndex): Implemented.
+ (AccessibleJTable.getAccessibleCaption): Implemented.
+ (AccessibleJTable.setAccessibleCaption): Implemented.
+ (AccessibleJTable.getAccessibleSummary): Implemented.
+ (AccessibleJTable.setAccessibleSummary): Implemented.
+ (AccessibleJTable.getAccessibleRowCount): Implemented.
+ (AccessibleJTable.getAccessibleColumnCount): Implemented.
+ (AccessibleJTable.getAccessibleAt): Implemented.
+ (AccessibleJTable.getAccessibleRowExtentAt): Implemented.
+ (AccessibleJTable.getAccessibleColumnExtentAt): Implemented.
+ (AccessibleJTable.getAccessibleRowHeader): Implemented.
+ (AccessibleJTable.setAccessibleRowHeader): Implemented.
+ (AccessibleJTable.getAccessibleColumnHeader): Implemented.
+ (AccessibleJTable.setAccessibleColumnHeader): Implemented.
+ (AccessibleJTable.getAccessibleRowDescription): Implemented.
+ (AccessibleJTable.setAccessibleRowDescription): Implemented.
+ (AccessibleJTable.getAccessibleColumnDescription): Implemented.
+ (AccessibleJTable.setAccessibleColumnDescription): Implemented.
+ (AccessibleJTable.isAccessibleSelected): Implemented.
+ (AccessibleJTable.isAccessibleRowSelected): Implemented.
+ (AccessibleJTable.isAccessibleColumnSelected): Implemented.
+ (AccessibleJTable.getSelectedAccessibleRows): Implemented.
+ (AccessibleJTable.getSelectedAccessibleColumns): Implemented.
+ (getAccessibleContext): Register listeners for the accessibility
+ class on the JTable.
+
+2006-06-01 Sven de Marothy <sven@physto.se>
+
+ * gnu/java/awt/peer/gtk/CairoGraphics2D.java:
+ (setPaint): Scale +1 pixel larger.
+
+2006-06-01 Sven de Marothy <sven@physto.se>
+
+ PR 27854
+ * gnu/java/awt/Buffers.java (getData): Reimplement.
+ * gnu/java/awt/peer/gtk/CairoSurface.java
+ (getElem, setElem): Call native methods.
+
+2006-06-01 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * gnu/javax/swing/text/html/ImageViewIconFactory.java: New file.
+
+2006-06-01 Sven de Marothy <sven@physto.se>
+
+ * gnu/java/awt/peer/gtk/CairoGraphics2D.java
+ (drawImage): Check for zero size.
+ * gnu/java/awt/peer/gtk/GdkTextLayout.java:
+ (setFont): Declare new native method.
+ (GdkTextLayout): Read some attributes.
+ * include/gnu_java_awt_peer_gtk_GdkTextLayout.h
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c
+ (setFont): New native method.
+
+2006-06-01 Sven de Marothy <sven@physto.se>
+
+ * gnu/java/awt/peer/gtk/BufferedImageGraphics.java
+ (updateBufferedImage): Fix some errors.
+
+2006-06-01 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/plaf/basic/BasicButtonUI.java: Minor source code style
+ fixes,
+ * javax/swing/plaf/basic/BasicDirectoryModel.java: Likewise,
+ * javax/swing/plaf/basic/BasicFileChooserUI.java: Likewise,
+ * javax/swing/plaf/basic/BasicIconFactory.java: Likewise,
+ * javax/swing/plaf/basic/BasicListUI.java: Likewise,
+ * javax/swing/plaf/basic/BasicOptionPaneUI.java: Likewise,
+ * javax/swing/plaf/basic/BasicRootPaneUI.java: Likewise,
+ * javax/swing/plaf/basic/BasicScrollPaneUI.java: Likewise,
+ * javax/swing/plaf/basic/BasicSpinnerUI.java: Likewise,
+ * javax/swing/plaf/basic/BasicTabbedPaneUI.java: Likewise,
+ * javax/swing/plaf/basic/BasicTextAreaUI.java: Likewise.
+
+2006-06-01 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JComboBox.java: Minor source code formatting fixes,
+ * javax/swing/JEditorPane.java: Likewise,
+ * javax/swing/JFormattedTextField.java: Likewise,
+ * javax/swing/JLayeredPane.java: Likewise,
+ * javax/swing/JScrollPane.java: Likewise,
+ * javax/swing/JSlider.java: Likewise,
+ * javax/swing/JSpinner.java: Likewise,
+ * javax/swing/JTree.java: Likewise,
+ * javax/swing/JViewport.java: Likewise,
+ * javax/swing/UIDefaults.java: Likewise,
+ * javax/swing/UIManager.java: Likewise.
+
+2006-06-01 Sven de Marothy <sven@physto.se>
+
+ * gnu/java/awt/peer/gtk/BufferedImageGraphics.java
+ (BufferedImageGraphics): Cache surfaces.
+ (updateBufferedImage): Copy directly for certain color models.
+ * gnu/java/awt/peer/gtk/CairoGraphics2D.java
+ (drawImage): Reimplement.
+
+2006-06-01 Sven de Marothy <sven@physto.se>
+
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c
+ (setPixels): Don't swap, correct size.
+
+2006-05-31 Anthony Green <green@redhat.com>
+
+ PR 27828
+ * java/net/InetSocketAddress.java: Defer getting the host
+ name until somebody calls InetSocketAddress.getHostName().
+ Fix "represenation" typo.
+
+2006-06-01 Sven de Marothy <sven@physto.se>
+
+ * gnu/java/awt/peer/gtk/BufferedImageGraphics.java
+ (updateBufferedImage): Simplify.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c
+ (getPixels): Don't swap.
+
+2006-06-01 Sven de Marothy <sven@physto.se>
+
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c
+ (setGradient): Reimplement.
+
+2006-06-01 Andreas Tobler <a.tobler@schweiz.ch>
+
+ * native/jni/gtk-peer/cairographics2d.h: Rename/prefix function
+ CairoGraphics2D_getCairoT to cp_gtk_get_cairo_t correctly.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c
+ (Java_gnu_java_awt_peer_gtk_CairoSurface_drawSurface): Rename function
+ CairoGraphics2D_getCairoT to cp_gtk_get_cairo_t.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c
+ (Java_gnu_java_awt_peer_gtk_GdkTextLayout_cairoDrawGdkTextLayout):
+ Likewise.
+
+2006-05-31 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/table/JTableHeader.java
+ (getColumnHeaderRenderer): New method,
+ (getAccessibleColumnHeaderRenderer): Delegate part to new
+ getColumnHeaderRenderer() method,
+ (getLocale): Implemented.
+
+2006-05-31 Andreas Tobler <a.tobler@schweiz.ch>
+
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphics.c
+ (cp_gtk_grab_current_drawable): Rename
+ cp_java_awt_peer_gtk_ComponentGraphics_grab_current_drawable to
+ cp_gtk_grab_current_drawable, remove static declaration.
+ (Java_gnu_java_awt_peer_gtk_ComponentGraphics_initState): Renamed above
+ function.
+ (Java_gnu_java_awt_peer_gtk_ComponentGraphics_copyAreaNative): Likewise.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphicsCopy.c:
+ Remove prototype of
+ cp_java_awt_peer_gtk_ComponentGraphics_grab_current_drawable.
+ (Java_gnu_java_awt_peer_gtk_ComponentGraphicsCopy_getPixbuf): Rename
+ function.
+ (Java_gnu_java_awt_peer_gtk_ComponentGraphicsCopy_copyPixbuf): Likewise.
+ * native/jni/gtk-peer/gtkpeer.h: Add prototype for
+ cp_gtk_grab_current_drawable here.
+
+2006-05-31 Sven de Marothy <sven@physto.se>
+
+ Should fix PR 27835
+ * gnu/java/awt/peer/gtk/BufferedImageGraphics.java
+ (updateBufferedImage): Keep within image bounds.
+
+2006-05-31 Thomas Fitzsimmons <fitzsim@redhat.com>
+ Andreas Tobler <a.tobler@schweiz.ch>
+
+ * configure.ac: Check for libXrender when the GTK peers are
+ enabled, and set HAVE_XRENDER accordingly. Add -lXrender to
+ X_EXTRA_LIBS.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphics.c
+ (Java_gnu_java_awt_peer_gtk_ComponentGraphics_hasXRender)
+ [HAVE_XRENDER]: Call XRenderQueryExtension conditionally.
+
+2006-05-31 Lillian Angel <langel@redhat.com>
+
+ * javax/swing/plaf/basic/BasicProgressBarUI.java
+ (paintString): Implemented to paint the string vertically.
+
+2006-05-31 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JTable.java
+ (AccessibleJTable.AccessibleJTable()): Check for null editor,
+ (AccessibleJTable.getAccessibleRole()): Overridden to return correct
+ value,
+ (AccessibleJTable.getAccessibleTable()): Likewise,
+ (getAccessibleContext): Create new context if required.
+
+2006-05-31 Roman Kennke <kennke@aicas.com>
+
+ * javax/swing/JTabbedPane.java
+ (AccessibleJTabbedPane.stateChanged): Implemented.
+ (Page.getAccessibleStateSet): Implemented.
+ (Page.getAccessibleIndexInParent): Implemented.
+ (getAccessibleContext): Add AccessibleJTabbedPane object
+ as ChangeListener to the JTabbedPane.
+
+2006-05-31 Roman Kennke <kennke@aicas.com>
+
+ * javax/swing/JMenuItem.java
+ (getAccessibleContext): Register accessible object as ChangeListener
+ to the JMenuItem.
+ (AccessibleJMenuItem.armed): New field.
+ (AccessibleJMenuItem.focusOwner): New field.
+ (AccessibleJMenuItem.pressed): New field.
+ (AccessibleJMenuItem.selected): New field.
+ (stateChanged): Implemented.
+
+2006-05-31 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/ListSelectionModel.java: Added API docs all over.
+
+2006-05-31 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * examples/gnu/classpath/examples/swing/FillRect.java
+ (paintComponent): Optionally paint lines rather than rectangles.
+ (createContent): Added option to test line painting.
+
+2006-05-31 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/event/EventListenerList.java
+ (getListenerList): Updated API docs.
+
+2006-05-30 Sven de Marothy <sven@physto.se>
+
+ * gnu/java/awt/peer/gtk/CairoGraphics2D.java
+ (drawImage): Clip scaled image to dest rectangle.
+
+2006-05-30 Sven de Marothy <sven@physto.se>
+
+ * gnu/java/awt/peer/gtk/CairoSurface.java:
+ (CairoSurface): Convert pixels properly.
+ * gnu/java/awt/peer/gtk/ComponentGraphics.java
+ Remove commented-out lines.
+
+2006-05-30 Sven de Marothy <sven@physto.se>
+
+ * gnu/java/awt/peer/gtk/CairoGraphics2D.java
+ (drawImage): Use Toolkit to convert to BufferedImage.
+ * gnu/java/awt/peer/gtk/CairoSurface.java
+ (CairoSurface(GtkImage)): New Constructor.
+ (getBufferedImage): New method.
+ * gnu/java/awt/peer/gtk/ComponentGraphics.java
+ Don't fill background - FIXME.
+ * gnu/java/awt/peer/gtk/GdkPixbufDecoder.java:
+ Remove unused methods.
+ * gnu/java/awt/peer/gtk/GtkImage.java:
+ (pixbuflock): New field. Methods change to use this lock.
+ * gnu/java/awt/peer/gtk/GtkToolkit.java
+ (createImage): Use Cairo-backed surfaces via GtkImage instead of
+ GtkPixbufDecoder.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c
+ (setPixels): Correct length in bytes.
+
+2006-05-30 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * gnu/java/awt/peer/gtk/CairoGraphics2D.java (static): Call
+ System.loadLibrary unconditionally.
+ * gnu/java/awt/peer/gtk/GdkFontPeer.java: Likewise.
+ * gnu/java/awt/peer/gtk/GdkPixbufDecoder.java: Likewise.
+ * gnu/java/awt/peer/gtk/GdkTextLayout.java: Likewise.
+ * gnu/java/awt/peer/gtk/GtkToolkit.java: Likewise.
+
+2006-05-30 Mark Wielaard <mark@klomp.org>
+
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphics.c
+ (Java_gnu_java_awt_peer_gtk_ComponentGraphics_copyAreaNative):
+ Mark unused parameters, remove unused variables.
+
+2006-05-30 Sven de Marothy <sven@physto.se>
+
+ * gnu/java/awt/peer/gtk/ComponentGraphics.java
+ (copyArea): Implemented.
+ * include/gnu_java_awt_peer_gtk_ComponentGraphics.h
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphics.c:
+ (copyAreaNative): New method.
+
+2006-05-30 Andreas Tobler <a.tobler@schweiz.ch>
+
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c
+ (Java_gnu_java_awt_peer_gtk_CairoSurface_getPixels): Define i only
+ for non big endian systems.
+ (Java_gnu_java_awt_peer_gtk_CairoSurface_setPixels): Likewise.
+
+2006-05-30 Roman Kennke <kennke@aicas.com>
+
+ * gnu/java/awt/java2d/TexturePaintContext.java: New file.
+ * java/awt/TexturePaint.java
+ (createContext): Implemented.
+
+2006-05-30 Robert Schuster <robertschuster@fsfe.org>
+
+ * java/awt/Container.java:
+ (removeAll): Reimplemented, added note.
+
+2006-05-30 Robert Schuster <robertschuster@fsfe.org>
+
+ * java/awt/Container.java:
+ (removeAll): Implemented different removal mechanism, added note.
+
+2006-05-30 Lillian Angel <langel@redhat.com>
+
+ PR 27785
+ * java/awt/Component.java:
+ (translateEvent): Added handling to translate WindowEvents
+ * java/awt/Window.java:
+ Removed unneeded imports.
+
+2006-05-30 Mark Wielaard <mark@klomp.org>
+
+ * native/jni/gtk-peer/Makefile.am (libgtkpeer_la_SOURCES): Add
+ cairographics2d.h.
+
+2006-05-30 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * gnu/java/awt/peer/gtk/GtkImage.java: Fix constructor javadoc.
+
+2006-05-29 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * gnu/java/awt/peer/gtk/CairoGraphics2D.java
+ (clearRect): Do not reuse the fg field, call updateColor.
+ (drawRaster): Likewise.
+ (setColor): Call updateColor.
+ (updateColor): New method.
+
+2006-05-30 Mark Wielaard <mark@klomp.org>
+
+ * native/jni/classpath/jcl.h (JLONG_TO_PTR): New macro.
+ (PTR_TO_JLONG): Likewise.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c
+ (getPointer): Use new conversion macros.
+ (Java_gnu_java_awt_peer_gtk_CairoGraphics2D_init): Likewise.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c
+ (Java_gnu_java_awt_peer_gtk_CairoSurface_newCairoContext):
+ Likewise.
+ (setNativeObject): Likewise.
+ (getNativeObject): Likewise.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphics.c
+ (cp_java_awt_peer_gtk_ComponentGraphics_grab_current_drawable):
+ Mark static.
+ (Java_gnu_java_awt_peer_gtk_ComponentGraphics_initState):
+ Correctly cast XID and pointer values.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphicsCopy.c
+ (Java_gnu_java_awt_peer_gtk_ComponentGraphicsCopy_getPixbuf):
+ Mark unused variables.
+ (Java_gnu_java_awt_peer_gtk_ComponentGraphicsCopy_copyPixbuf):
+ Likewise.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c
+ (Java_gnu_java_awt_peer_gtk_GdkTextLayout_cairoDrawGdkTextLayout):
+ Remove unused cairographics2d struct.
+ (_moveTo, _lineTo, _quadTo, _curveTo): Mark arguments const.
+ (Java_gnu_java_awt_peer_gtk_GtkImage_initFromBuffer):
+ Use new conversion macros.
+ * native/jni/midi-dssi/dssi_data.h: Move conversion macros to jcl.h.
+
+2006-05-30 Mark Wielaard <mark@klomp.org>
+
+ * include/Makefile.am (gnu_java_nio_VMChannel.h): Added.
+
+2006-05-29 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * gnu/java/awt/peer/gtk/CairoGraphics2D.java
+ (copy): Do not reuse the fd field.
+ (setColor): Do not set the color if the parameter
+ matches fd field.
+ (translate(double, double): Rewritten to use
+ AffineTransform.translate.
+
+2006-05-30 Sven de Marothy <sven@physto.se>
+
+ * gnu/java/awt/peer/gtk/ComponentGraphicsCopy.java
+ * include/gnu_java_awt_peer_gtk_ComponentGraphicsCopy.h
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphicsCopy.c
+ New files.
+ * include/Makefile.am
+ * native/jni/gtk-peer/Makefile.am
+ Add new files.
+ * gnu/java/awt/peer/gtk/CairoSurface.java
+ (getSharedGtkImage): New method.
+ * gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c
+ Fix copyArea.
+ * gnu/java/awt/peer/gtk/ComponentGraphics.java
+ Support a non-xrender context.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphics.c
+ Plug memory leak.
+ * gnu/java/awt/peer/gtk/GtkImage.java
+ * include/gnu_java_awt_peer_gtk_GtkImage.h
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c
+ (initFromBuffer): New method.
+ * native/jni/gtk-peer/gtkpeer.h:
+ Remove declarations of previouslyremoved methods.
+
+2006-05-29 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * tools/Makefile.am [FOUND_CACAO] (LIBJVM): Define to -ljvm.
+
+2006-05-29 Mark Wielaard <mark@klomp.org>
+
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c
+ (Java_gnu_java_awt_peer_gtk_CairoGraphics2D_init): Mark unused
+ arguments.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c
+ (Java_gnu_java_awt_peer_gtk_CairoSurface_setPixels): Declare size
+ early. Remove unused return statement in void function.
+ (Java_gnu_java_awt_peer_gtk_CairoSurface_newCairoContext): Declare
+ ptr early.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphics.c
+ (Java_gnu_java_awt_peer_gtk_ComponentGraphics_hasXRender): Mark
+ unused arguments.
+ (Java_gnu_java_awt_peer_gtk_ComponentGraphics_initState): Likewise.
+ (Java_gnu_java_awt_peer_gtk_ComponentGraphics_start_1gdk_1drawing):
+ Likewise.
+ (Java_gnu_java_awt_peer_gtk_ComponentGraphics_end_1gdk_1drawing):
+ Likewise.
+
+2006-05-29 Sven de Marothy <sven@physto.se>
+
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c
+ (setPixels): Remove superfluous return statement.
+
+2006-05-29 Sven de Marothy <sven@physto.se>
+
+ * gnu/java/awt/peer/gtk/BufferedImageGraphics.java
+ * gnu/java/awt/peer/gtk/CairoGraphics2D.java
+ * gnu/java/awt/peer/gtk/CairoSurface.java
+ * gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java
+ * gnu/java/awt/peer/gtk/ComponentGraphics.java
+ * include/gnu_java_awt_peer_gtk_CairoGraphics2D.h
+ * include/gnu_java_awt_peer_gtk_CairoSurface.h
+ * include/gnu_java_awt_peer_gtk_ComponentGraphics.h
+ * native/jni/gtk-peer/cairographics2d.h
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphics.c
+ New files.
+
+ * gnu/java/awt/peer/gtk/GdkGraphics2D.java
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
+ * include/gnu_java_awt_peer_gtk_GdkGraphics2D.h
+ Removed
+
+ * include/gnu_java_awt_peer_gtk_GdkFontPeer.h
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c
+ * gnu/java/awt/peer/gtk/GdkFontPeer.java
+ (releasePeerGraphicsResource): Moved to Font peer class.
+
+ * gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java
+ (createGraphics): Use new context classes.
+
+ * gnu/java/awt/peer/gtk/GdkPixbufDecoder.java:
+ Use native BufferedImages where possible.
+
+ * gnu/java/awt/peer/gtk/GdkTextLayout.java
+ * include/gnu_java_awt_peer_gtk_GdkTextLayout.h
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c
+ Move GdkGraphics2D.drawGdkTextLayout to the GdkTextLayout class,
+ renamed to cairoDrawGdkTextLayout.
+
+ * gnu/java/awt/peer/gtk/GtkComponentPeer.java
+ (getGraphics): Use ComponentGraphics context.
+ (createImage): Use native BufferedImage.
+
+ * gnu/java/awt/peer/gtk/GtkImage.java:
+ * include/gnu_java_awt_peer_gtk_GtkImage.h
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c
+ Remove pixmap support. (GtkImage(int, int) constructor, getGraphics)
+ Remove drawing methods.
+
+ * gnu/java/awt/print/JavaPrinterGraphics.java:
+ Use CairoSurface instead of GtkImage.
+
+ * include/Makefile.am
+ * native/jni/gtk-peer/Makefile.am
+ Update for new files.
+
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c
+ Remove superfluous GtkImage code for GdkPixmaps.
+
+ * native/jni/gtk-peer/gtkpeer.h
+ Remove graphics2d structure.
+
+2006-05-29 Mark Wielaard <mark@klomp.org>
+
+ * java/io/ObjectStreamConstants.java: Removed double declaration
+ of SC_ENUM.
+
+2006-05-29 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * gnu/java/awt/peer/gtk/GdkGraphics2D.java (copying constructor):
+ Do not reuse fg in the constructor.
+
+2006-05-29 Carsten Neumann <cn-develop@gmx.net>
+
+ * java/io/ObjectStreamConstants.java: Added API docs.
+
+2006-05-29 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * gnu/java/awt/peer/gtk/GdkGraphics2D.java (setColor):
+ Take no action if this color is already set.
+
+2006-05-29 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * gnu/java/awt/peer/gtk/GdkGraphics2D.java (translate):
+ Rewritten.
+ * examples/gnu/classpath/examples/swing/FillRect.java (paintComponent):
+ Optionally paint with translation. (createContent): Added option
+ to test painting with translation
+
+2006-05-29 Raif S. Naffah <raif@swiftdsl.com.au>
+
+ * java/util/logging/FileHandler.java (FileHandler): Set the instance field
+ pattern to the default value when null.
+ Pass field pattern, and not parameter with same name to createFileStream.
+
+2006-05-28 Andrew John Hughes <gnu_andrew@member.fsf.org>
+
+ * gnu/java/lang/management/OperatingSystemMXBeanImpl.java:
+ New class implementing the OS bean.
+ * gnu/java/lang/management/package.html:
+ New file to document the gnu.java.lang.management package.
+ * java/lang/management/ManagementFactory.java:
+ New class to provide access to the OS bean.
+ * java/lang/management/OperatingSystemMXBean.java:
+ New interface.
+ * java/lang/management/package.html:
+ New file to document the java.lang.management package.
+
+2006-05-28 Raif S. Naffah <raif@swiftdsl.com.au>
+
+ * tools/gnu/classpath/tools/keytool/ImportCmd.java (GKR): New constant.
+ (JKS): Likewise.
+ (LIB): Likewise.
+ (SECURITY): Likewise.
+ (CACERTS): Likewise.
+ (CACERTS_GKR): Likewise.
+ (gkrCaCertsPathName): New field.
+ (jksCaCertsPathName): Likewise.
+ (selfSignedCertificate): Likewise.
+ (start): Initialize trusted certificate key stores if -trustcacerts is
+ specified.
+ (ensureReplyIsOurs): Initialize selfSignedCertificate.
+ (orderChain): Implemented.
+ (findTrustAndUpdate): Check a cacerts.gkr (GKR) and a cacert (JKS) trusted
+ certificate key stores if -trustcacerts option is specified.
+ (findTrustInCACerts): Removed.
+ (getCertPathParameters): New method.
+ (validate): New method.
+ * resource/gnu/classpath/tools/keytool/messages.properties: Added message.
+
+2006-05-28 Raif S. Naffah <raif@swiftdsl.com.au>
+
+ * java/util/logging/FileHandler.java (PROPERTY_PREFIX): New constant.
+ (PATTERN_KEY): Likewise.
+ (DEFAULT_PATTERN): Likewise.
+ (LIMIT_KEY): Likewise.
+ (DEFAULT_LIMIT): Likewise.
+ (COUNT_KEY): Likewise.
+ (DEFAULT_COUNT): Likewise.
+ (APPEND_KEY): Likewise.
+ (DEFAULT_APPEND): Likewise.
+ (FileHandler()): Use pattern value as set in logging.properties.
+ Use constants defined above.
+ (FileHandler(1)): Use constants defined above.
+ (FileHandler(2)): Likewise.
+ (FileHandler(3)): Likewise.
+ (FileHandler(4)): Likewise.
+ (createFileStream): Likewise.
+
+2006-05-28 Raif S. Naffah <raif@swiftdsl.com.au>
+
+ * java/util/logging/FileHandler.java: Reverted previous patch.
+ * java/util/logging/LogManager.java: Likewise.
+
+2006-05-28 Raif S. Naffah <raif@swiftdsl.com.au>
+
+ * java/util/logging/FileHandler.java (PATTERN_KEY): New constant.
+ (DEFAULT_PATTERN): Likewise.
+ (FileHandler()): Use configured pattern property if any; otherwise use a
+ default value as per RI documentation.
+ * java/util/logging/LogManager.java (getStringProperty): New method.
+
+2006-05-27 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * NEWS: Announce libjawtgnu.so-to-libjawt.so rename.
+
+2006-05-27 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * configure.ac (FOUND_CACAO): New automake conditional.
+ Add --enable-tool-wrappers.
+ * NEWS: Introduce the --enable-tool-wrappers option.
+ * tools/Makefile.am[CREATE_WRAPPERS]: Build wrapper binaries.
+ * tools/appletviewer.c: Remove file. Make tool-indepedent and
+ rename ...
+ * tools/toolwrapper.c: New file.
+
+2006-05-27 Dalibor Topic <robilad@kaffe.org>
+
+ * java/awt/Graphics2D.java: Use full class name for
+ PrinterJob in javadoc.
+
+2006-05-27 Andreas Tobler <a.tobler@schweiz.ch>
+
+ * native/jni/qt-peer/eventmethods.h (callVoidMethod): Silence warning.
+ (callMouseMethod): Likewise.
+
+2006-05-26 Andrew John Hughes <gnu_andrew@member.fsf.org>
+
+ * native/jni/java-net/java_net_VMURLConnection.c:
+ Fix function declarations to specify unused parameters.
+ * scripts/check_jni_methods.sh:
+ Remove copies of the same function using uniq.
+
+2006-05-26 Andrew John Hughes <gnu_andrew@member.fsf.org>
+
+ * vm/reference/java/net/VMURLConnection.java:
+ Make package-private and final.
+
+2006-05-27 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * examples/gnu/classpath/examples/swing/TableDemo.java
+ (TModed): Added editor for the icons column.
+ (createContent): Increase the row height by 2 px.
+
+2006-05-26 Tom Tromey <tromey@redhat.com>
+
+ PR classpath/27685:
+ * java/math/BigInteger.java (modPow): Correctly handle negative
+ exponent.
+
+2006-05-26 Tom Tromey <tromey@redhat.com>
+
+ * configure.ac: Check for magic.h and -lmagic.
+ * vm/reference/java/net/VMURLConnection.java: New file.
+ * include/java_net_VMURLConnection.h: New file.
+ * include/Makefile.am (H_FILES): Add VMURLConnection.h.
+ ($(top_srcdir)/include/java_net_VMURLConnection.h): New target.
+ * native/jni/java-net/Makefile.am (libjavanet_la_SOURCES):
+ Mention new file.
+ (libjavanet_la_LIBADD): Add $(LIBMAGIC).
+ * native/jni/java-net/java_net_VMURLConnection.c: New file.
+
+2006-05-26 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * tools/Makefile.am (installcheck-binSCRIPTS): Do nothing.
+
+2006-05-26 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * native/jawt/Makefile.am (nativeexeclib_LTLIBRARIES): Rename
+ libjawtgnu.la libjawt.la.
+
+2006-05-26 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * native/jni/gtk-peer/Makefile.am (libgtkpeer_la_SOURCES): Remove
+ gtkcairopeer.h.
+
+2006-05-25 Lillian Angel <langel@redhat.com>
+
+ PR 26174
+ * java/awt/Window.java
+ (Window): Moved code to helper.
+ (addWindowFocusListener): New function. Handles focus
+ listener code. Added code to handle focus lost/gained
+ from the window.
+
+2006-05-25 Andrew John Hughes <gnu_andrew@member.fsf.org>
+
+ * configure.ac:
+ Make pkg-config check for GTK+ >= 2.8.
+
+2006-05-25 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
+ (flush): Remove debugging printfs.
+
+2006-05-25 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
+ (schedule_flush): New function.
+ (end_drawing_operation): Call schedule_flush.
+
+2006-05-25 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * examples/gnu/classpath/examples/swing/Demo.java: Add FillRect
+ paint performance demo.
+ * examples/gnu/classpath/examples/swing/FillRect.java: New file.
+
+2006-05-25 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * INSTALL: Bump GTK requirement to 2.8 or higher. Do not mention
+ Cairo version requirement. Do not mention --enable-gtk-cairo
+ configure option.
+ * NEWS: Add entry for GdkGraphics2D.
+ * configure.ac: Remove --enable-gtk-cairo and explicit checks for
+ Cairo library and headers.
+ * .externalToolBuilders/Configure.launch: Remove
+ --enable-gtk-cairo from configure line.
+ * gnu/classpath/Configuration.java.in (GTK_CAIRO_ENABLED): Remove
+ field.
+ * gnu/java/awt/BitwiseXORComposite.java: Fix javadoc typo.
+ * gnu/java/awt/peer/gtk/GdkFontPeer.java,
+ native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c : Remove
+ useGraphics2D references. Always assume Graphics2D is enabled.
+ * gnu/java/awt/peer/gtk/GdkGraphics.java,
+ native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c: Remove.
+ * gnu/java/awt/peer/gtk/GdkGraphics2D.java,
+ native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c: Remove
+ Unlocked method variants. Remove GTK_CAIRO_ENABLED and
+ useGraphics2D references. Always assume Graphics2D is enabled.
+ * gnu/java/awt/peer/gtk/GdkTextLayout.java: Remove instanceof
+ Graphics2D check. Always assume Graphics2D is enabled.
+ * gnu/java/awt/peer/gtk/GtkCanvasPeer.java,
+ native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.c
+ (realize): Remove method.
+ * gnu/java/awt/peer/gtk/GtkComponentPeer.java,
+ native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c
+ (isRealized): Remove method.
+ (realize): Implement as a native method. Remove useGraphics2D
+ references. Always assume Graphics2D is enabled.
+ * gnu/java/awt/peer/gtk/GtkImage.java,
+ native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c: Replace
+ GdkGraphics references with GdkGraphics2D references.
+ * gnu/java/awt/peer/gtk/GtkToolkit.java,
+ native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c: Remove
+ useGraphics2D references. Always assume Graphics2D is enabled.
+ * include/Makefile.am (GTKPEER_H_FILES): Remove
+ gnu_java_awt_peer_gtk_GdkGraphics.h.
+ * include/gnu_java_awt_peer_gtk_GdkFontPeer.h: Regenerate.
+ * include/gnu_java_awt_peer_gtk_GdkGraphics.h: Remove.
+ * include/gnu_java_awt_peer_gtk_GdkGraphics2D.h: Regenerate.
+ * include/gnu_java_awt_peer_gtk_GtkCanvasPeer.h: Likewise.
+ * include/gnu_java_awt_peer_gtk_GtkComponentPeer.h: Likewise.
+ * native/jawt/Makefile.am (AM_LDFLAGS): Remove CAIRO_LIBS.
+ * native/jni/gtk-peer/Makefile.am (libgtkpeer_la_SOURCES): Remove
+ gnu_java_awt_peer_gtk_GdkGraphics.c. Include
+ gnu_java_awt_peer_gtk_GdkGraphics2D.c unconditionally.
+ (AM_LDFLAGS): Remove CAIRO_LIBS.
+ (AM_CFLAGS): Remove CAIRO_CFLAGS.
+ * native/jni/gtk-peer/gtkcairopeer.h: Remove. Move declarations
+ to ...
+ * native/jni/gtk-peer/gtkpeer.h: Add Graphics2D declarations.
+
+2006-05-25 Lillian Angel <langel@redhat.com>
+
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c
+ (Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetCursorUnlocked):
+ Added check to prevent assertion error. If widget->window is null, then
+ use the parent widget's window to set the cursor on.
+
+2006-05-25 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/plaf/basic/BasicTreeUI.java (TreeCancelEditingAction):
+ Implemented.
+
+2006-05-24 Lillian Angel <langel@redhat.com>
+
+ * tools/gnu/classpath/tools/appletviewer/AppletTag.java
+ (prependCodeBase): Added check to determine if the documentbase
+ points to a directory or a file.
+
+2006-05-24 Sven de Marothy <sven@physto.se>
+
+ * java/awt/dnd/DragGestureRecognizer.java
+ (resetRecognizer): Implement.
+ (fireDragGestureRecognized): Implement.
+
+2006-05-24 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/plaf/basic/BasicComboBoxUI.java: Marked stub methods and
+ fixed source code formatting.
+
+2006-05-24 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/JTable.java (valueChanged): If is editing, stop editing.
+
+2006-05-24 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ Reported by Antony Balkisson.
+ * javax/swing/JTable.java (selectAll): Return without action
+ if the table is empty.
+
+2006-05-23 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * examples/gnu/classpath/examples/swing/TableDemo.java:
+ (SliderCell): New inner class. (setCustomEditors,
+ setInformativeHeaders): New fields. (createContent):
+ Rewritten.
+ * javax/swing/DefaultCellEditor.java
+ (JComboBoxDelegate.shouldSelectCell): New method.
+ * javax/swing/JTable.java (editCellAt): Call shouldSelectCell.
+ * javax/swing/plaf/basic/BasicTableUI.java
+ (MouseInputHandler.mouseClicked): Start editing on a single
+ click if the cell editor is not a default cell editor.
+
+2006-05-23 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/naming/CompositeName.java,
+ javax/swing/naming/CompoundName.java:
+ Documented.
+
+2006-05-23 Archie Cobbs <archie@dellroad.org>
+
+ * vm/reference/java/lang/VMClassLoader.java: fix static initializer
+ ordering problem.
+
+2006-05-23 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/tree/AbstractLayoutCache.java: Coding style fixes,
+ * javax/swing/tree/DefaultMutableTreeNode.java: Likewise,
+ * javax/swing/tree/DefaultTreeCellRenderer.java: Likewise,
+ * javax/swing/tree/DefaultTreeModel.java: Likewise,
+ * javax/swing/tree/DefaultTreeSelectionModel.java: Likewise,
+ * javax/swing/tree/ExpandVetoException.java: Likewise,
+ * javax/swing/tree/FixedHeightLayoutCache.java: Likewise,
+ * javax/swing/tree/RowMapper.java: Likewise,
+ * javax/swing/tree/TreeNode.java: Likewise,
+ * javax/swing/tree/TreeSelectionModel.java: Likewise,
+ * javax/swing/tree/VariableHeightLayoutCache.java: Likewise.
+
+2006-05-23 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/tree/DefaultTreeCellRenderer.java
+ (DefaultTreeCellRenderer): Changed key for
+ setBackgroundNonSelectionColor(),
+ plus API docs all over.
+
+2006-05-23 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ PR 27680
+ * javax/swing/JTable.java (booleanInvertingEditor): New field.
+ (defaultEditorsByColumnClass, defaultRenderersByColumnClass):
+ Initialise in constructor. (columnMoved): Cancel editing.
+ (createDefaultEditors): Rewritten. (editCellAt):
+ Just invert the value if this is a boolean cell.
+ (initialiseLocalVars): Do not initialise renderer and editor tables.
+ (setUI): Create editors and renderers here.
+
+2006-05-23 Robert Schuster <robertschuster@fsfe.org>
+
+ * examples/gnu/classpath/examples/awt/Demo.java:
+ (MainWindow.MainWindow): Added ResolutionWindow and FullscreenWindow
+ instance as subframe.
+ (ResolutionWindow): New inner class.
+ (FullscreenWindow): New inner class.
+
+2006-05-23 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ PR 27680
+ * javax/swing/JTable.java (BooleanCellRenderer, IconCellRenderer):
+ Set horizontal alignment to centered.
+
+2006-05-22 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/accessibility/AccessibleContext.java
+ (getAccessibleComponent): Fixed typo in docs,
+ * javax/swing/JLabel.java:
+ (AccessibleJLabel.getAccessibleName): Check for explicit
+ accessibleName,
+ * javax/swing/JTableHeader.java
+ (AccessibleJTableHeaderEntry.columnIndex): New field,
+ (AccessibleJTableHeaderEntry.parent): New field,
+ (AccessibleJTableHeaderEntry.table): New field,
+ (AccessibleJTableHeaderEntry.AccessibleJTableHeaderEntry()):
+ Implemented,
+ (AccessibleJTableHeaderEntry.getAccessibleColumnHeaderRenderer): New
+ utility method,
+ (AccessibleJTableHeaderEntry.addFocusListener): Implemented,
+ (AccessibleJTableHeaderEntry.addPropertyChangeListener): Implemented,
+ (AccessibleJTableHeaderEntry.contains): Implemented,
+ (AccessibleJTableHeaderEntry.getAccessibleAction): Implemented,
+ (AccessibleJTableHeaderEntry.getAccessibleAt): Implemented,
+ (AccessibleJTableHeaderEntry.getAccessibleChild): Implemented,
+ (AccessibleJTableHeaderEntry.getAccessibleChildrenCount): Implemented,
+ (AccessibleJTableHeaderEntry.getAccessibleComponent): Implemented,
+ (AccessibleJTableHeaderEntry.getAccessibleContext): Implemented,
+ (AccessibleJTableHeaderEntry.getAccessibleDescription): Implemented,
+ (AccessibleJTableHeaderEntry.getAccessibleIndexInParent): Implemented,
+ (AccessibleJTableHeaderEntry.getAccessibleName): Implemented,
+ (AccessibleJTableHeaderEntry.getAccessibleRole): Implemented,
+ (AccessibleJTableHeaderEntry.getAccessibleSelection): Implemented,
+ (AccessibleJTableHeaderEntry.getAccessibleStateSet): Implemented,
+ (AccessibleJTableHeaderEntry.getAccessibleText): Implemented,
+ (AccessibleJTableHeaderEntry.getAccessibleValue): Implemented,
+ (AccessibleJTableHeaderEntry.getBackground): Implemented,
+ (AccessibleJTableHeaderEntry.getBounds): Implemented,
+ (AccessibleJTableHeaderEntry.getCursor): Implemented,
+ (AccessibleJTableHeaderEntry.getFont): Implemented,
+ (AccessibleJTableHeaderEntry.getFontMetrics): Implemented,
+ (AccessibleJTableHeaderEntry.getForeground): Implemented,
+ (AccessibleJTableHeaderEntry.getLocation): Implemented,
+ (AccessibleJTableHeaderEntry.getLocationOnScreen): Implemented,
+ (AccessibleJTableHeaderEntry.getSize): Implemented,
+ (AccessibleJTableHeaderEntry.isEnabled): Implemented,
+ (AccessibleJTableHeaderEntry.isFocusTraversable): Implemented,
+ (AccessibleJTableHeaderEntry.isShowing): Implemented,
+ (AccessibleJTableHeaderEntry.isVisible): Implemented,
+ (AccessibleJTableHeaderEntry.removeFocusListener): Implemented,
+ (AccessibleJTableHeaderEntry.removePropertyChangeListener):
+ Implemented,
+ (AccessibleJTableHeaderEntry.requestFocus): Implemented,
+ (AccessibleJTableHeaderEntry.setAccessibleDescription): Implemented,
+ (AccessibleJTableHeaderEntry.setAccessibleName): Implemented,
+ (AccessibleJTableHeaderEntry.setBackground): Implemented,
+ (AccessibleJTableHeaderEntry.setBounds): Implemented,
+ (AccessibleJTableHeaderEntry.setCursor): Implemented,
+ (AccessibleJTableHeaderEntry.setEnabled): Implemented,
+ (AccessibleJTableHeaderEntry.setFont): Implemented,
+ (AccessibleJTableHeaderEntry.setForeground): Implemented,
+ (AccessibleJTableHeaderEntry.setLocation): Implemented,
+ (AccessibleJTableHeaderEntry.setSize): Implemented,
+ (AccessibleJTableHeaderEntry.setVisible): Implemented,
+ (AccessibleJTableHeader.getAccessibleRole): Implemented,
+ (AccessibleJTableHeader.getAccessibleChildrenCount): Implemented,
+ (AccessibleJTableHeader.getAccessibleChild): Implemented,
+ (AccessibleJTableHeader.getAccessibleAt): Implemented.
+
+2006-05-22 Tom Tromey <tromey@redhat.com>
+
+ * NEWS: Updated.
+
+2006-05-22 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JLabel.java
+ (AccessibleJLabel.getAccessibleName): New method (override),
+ (setLabelFor): Fire 'labelFor' property change event before other
+ events.
+
+2006-05-22 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JLabel.java
+ (AccessibleJLabel.getAccessibleRole): New method (override).
+
+2006-05-22 Tom Tromey <tromey@redhat.com>
+
+ * resource/gnu/classpath/tools/serialver/messages.properties: New
+ file.
+ * tools/gnu/classpath/tools/serialver/Messages.java: New file.
+ * tools/gnu/classpath/tools/serialver/SerialVer.java (classes): New
+ field.
+ (classpath): Likewise.
+ (run): New method.
+ (main): Use it.
+ (addFileURL): New method.
+ (getClassLoader): Likewise.
+ (printMessage): Likewise.
+
+2006-05-22 Tom Tromey <tromey@redhat.com>
+
+ * tools/gnu/classpath/tools/serialver/SerialVer.java: New file.
+
+2006-05-22 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/JTable.java (doLayout): In the column
+ resize mode, only repaing the changed part of the table.
+ (getLeftResizingBoundary): New method.
+
+2006-05-22 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/naming/spi/InitialContextFactory.java,
+ javax/naming/spi/InitialContextFactoryBuilder.java,
+ javax/naming/spi/NamingManager.java,
+ javax/naming/spi/ObjectFactory.java,
+ javax/naming/spi/ResolveResult.java,
+ javax/naming/spi/Resolver.java,
+ javax/naming/spi/StateFactory.java: Documented.
+
+2006-05-21 Tom Tromey <tromey@redhat.com>
+
+ PR classpath/27688:
+ * tools/gnu/classpath/tools/jar/Extractor.java (allItems): Now
+ a WorkSet.
+ (initSet): Removed.
+ (shouldExtract): Removed.
+ (run): Updated.
+ * tools/gnu/classpath/tools/jar/WorkSet.java: New file.
+ * tools/gnu/classpath/tools/jar/Lister.java (readUntilEnd): New
+ method.
+ (listJar): Use it.
+ (allItems): New field.
+ (run): Initialize it.
+ (listJar): Use it.
+
+2006-05-22 Sven de Marothy <sven@physto.se>
+
+ * java/nio/CharBuffer.java
+ (wrap): Fix bounds checking.
+
+2004-08-26 Tom Tromey <tromey@redhat.com>
+
+ * java/io/OutputStream.java
+ (OutputStream): Implements Closeable, Flushable.
+
+2006-04-02 Andrew John Hughes <gnu_andrew@member.fsf.org>
+
+ * java/io/ObjectOutputStream.java:
+ (writeObject(Object)): Added enum support.
+ (writeClassDescriptor(ObjectStreamClass)): Likewise.
+ * java/io/ObjectStreamClass.java:
+ (isEnum()): New package-private method.
+ (setFlags(Class)): Added enum support.
+ * java/io/ObjectStreamConstants.java:
+ (SC_ENUM): Added.
+
+2006-03-29 Andrew John Hughes <gnu_andrew@member.fsf.org>
+
+ * java/io/ObjectInputStream.java:
+ (parseContent(byte)): Added enum support.
+ * java/io/ObjectStreamConstants.java:
+ (TC_ENUM): Added.
+ (TC_MAX): Changed to new maximum, TC_ENUM.
+
+2006-05-21 Andrew John Hughes <gnu_andrew@member.fsf.org>
+
+ * java/beans/beancontext/BeanContextSupport.java:
+ (instantiateChild(String)): Implemented.
+
+2006-05-21 Andrew John Hughes <gnu_andrew@member.fsf.org>
+
+ * java/beans/beancontext/BeanContextSupport.java:
+ (add(Object)): Add further documentation.
+ (isEmpty()): Documented.
+ (propertyChange(PropertyChangeEvent)): Implemented.
+ (remove(Object)): Documented.
+ (remove(Object,boolean)): Documented and implemented.
+ (vetoableChange(PropertyChangeEvent)): Marked as
+ implemented (only subclasses appear to need this).
+
+2006-05-21 Andrew John Hughes <gnu_andrew@member.fsf.org>
+
+ * java/beans/beancontext/BeanContextSupport.java:
+ (add(Object)): Implement support for the child being
+ a BeanContextChild.
+ (avoidingGui()): Implemented.
+ (dontUseGui()): Likewise.
+ (needsGui()): Likewise.
+ (okToUseGui()): Likewise.
+
+2006-05-21 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/naming/Context.java,
+ javax/naming/ContextNotEmptyException.java,
+ javax/naming/Reference.java: Documented.
+
+2006-05-21 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/text/html/MinimalHTMLWriter.java
+ (writeComponent, writeImage): Declare that the method
+ may throw the IOException.
+
+2006-05-21 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ PR 26972
+ * javax/naming/InitialContext.java (colon_list): Changed type to
+ hashset. (use_properties): New field. (init(Hashtable)): Rewritten.
+ (merge): Rewritten.
+
+2006-05-21 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/naming/InitialContext.java: Documented.
+
+2006-05-21 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/naming/NameParser.java,
+ javax/naming/NamingEnumeration.java,
+ javax/naming/PartialResultException.java,
+ javax/naming/SizeLimitExceededException.java,
+ javax/naming/spi/ObjectFactory.java,
+ javax/naming/spi/ObjectFactoryBuilder.java: Documented.
+
+2006-05-21 Andrew John Hughes <gnu_andrew@member.fsf.org>
+
+ * gnu/java/net/loader/JarURLLoader.java:
+ Use Map.Entry instead of LinkedHashMap.Entry
+
+2006-05-21 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/naming/Context.java: Documented.
+
+2006-05-21 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/naming/Referenceable.java: Documented.
+ * javax/naming/spi/NamingManager.java: Documented.
+
+2006-05-21 Raif S. Naffah <raif@swiftdsl.com.au>
+
+ * doc/tools.texinfo: Replaced references to MessageBundle.properties
+ to messages.properties.
+ * resource/gnu/classpath/tools/jarsigner/MessageBundle.properties:
+ Renamed to messages.properties.
+ * resource/gnu/classpath/tools/keytool/MessageBundle.properties:
+ Likewise.
+ * resource/gnu/classpath/tools/jarsigner/messages.properties:
+ Renamed from MessageBundle.properties.
+ Added copyright notice.
+ * resource/gnu/classpath/tools/keytool/messages.properties:
+ Likewise.
+ * tools/gnu/classpath/tools/jarsigner/Messages.java
+ (BUNDLE_NAME): Use messages instead of MessageBundle properties file.
+ (getFormattedString): Fixed a spelling mistake.
+ * tools/gnu/classpath/tools/keytool/Messages.java: Likewise.
+
+2006-05-20 Sven de Marothy <sven@physto.se>
+
+ * gnu/java/awt/font/opentype/NameDecoder.java
+ Made class public.
+ (getName): Use getShort instead of getChar(), fix PS name.
+ (decodeName): New method.
+ * gnu/java/awt/peer/gtk/GdkFontPeer.java
+ (getSubFamilyName): Implement.
+ (getPostScriptName): Use the NameDecoder class instead.
+ (parsePSName): Removed.
+ (getName): Added
+
+2006-05-20 Sven de Marothy <sven@physto.se>
+
+ * gnu/java/awt/peer/gtk/GdkFontPeer.java
+ (getTrueTypeTable): New native method.
+ (getPostScriptName): Reimplement.
+ (parsePSName): New method.
+ (getNumGlyphs): Implement.
+ * include/gnu_java_awt_peer_gtk_GdkFontPeer.h: New native method.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c
+ (Java_gnu_java_awt_peer_gtk_GdkFontPeer_getTrueTypeTable):
+ New function. File is now explicitly dependent on FT2.
+
+2006-05-20 Tom Tromey <tromey@redhat.com>
+
+ * tools/gnu/classpath/tools/native2ascii/Messages.java: New file.
+ * resource/gnu/classpath/tools/native2ascii/messages.properties: New
+ file.
+ * tools/gnu/classpath/tools/native2ascii/Native2ASCII.java
+ (HandleFile): New class.
+ (input, output, encoding, reversed): New fields.
+ (createParser): New method.
+ (run): Likewise.
+ (main): Use 'run'.
+ * tools/gnu/classpath/tools/getopt/FileArgumentCallback.java
+ (notifyFile): Throws OptionException.
+
+2006-05-20 Tom Tromey <tromey@redhat.com>
+
+ * tools/gnu/classpath/tools/native2ascii/Native2ASCII.java: New file,
+ from cp-tools.
+
+2006-05-20 Andrew John Hughes <gnu_andrew@member.fsf.org>
+
+ * native/jni/java-nio/gnu_java_nio_VMChannel.c:
+ (JCL_print_buffer): Fix to work with -Werror on 64-bit
+ platforms.
+
+2006-05-20 Sven de Marothy <sven@physto.se>
+
+ * java/awt/Font.java (getNumGlyphs): Call correct peer method.
+
+2006-05-20 Sven de Marothy <sven@physto.se>
+
+ * gnu/java/awt/print/JavaPrinterJob.java
+ (print): Use PostScriptGraphics2D.
+ * gnu/java/awt/print/PostScriptGraphics2D.java: New file.
+
+2006-05-20 Sven de Marothy <sven@physto.se>
+
+ * javax/swing/text/html/MinimalHTMLWriter.java: New file
+
+2006-05-20 Raif S. Naffah <raif@swiftdsl.com.au>
+
+ * gnu/java/security/OID.java: Updated copyright year.
+ (OID): Removed unused Javadoc param tag.
+ * gnu/java/security/prng/PRNGFactory.java: Removed unused import.
+ * gnu/java/security/hash/MD4.java: Fixed a Javadoc link.
+
+2006-05-20 Raif S. Naffah <raif@swiftdsl.com.au>
+
+ * gnu/javax/crypto/jce/keyring/GnuKeyring.java (engineAliases):
+ Formatting.
+ Added trace/debug statements.
+ (engineSetCertificateEntry): Ensure alias is not already used for a Key
+ Entry. Also ensure that any previous entry for this alias is removed
+ before a new one is added.
+ (engineGetKey): Do not trace/log passwords.
+ Trace key's class name only.
+ (engineSetKeyEntry): Ensure alias is not alredy used for a Trusted
+ Certificate Entry. Also ensure that previous entry for this alias is
+ removed before a new one is added.
+ (engineLoad): Do not trace/log passwords.
+ (engineStore): Likewise.
+ (engineSize): Use size of enumeration instead of collection size.
+
+2006-05-20 Raif S. Naffah <raif@swiftdsl.com.au>
+
+ * gnu/javax/crypto/keyring/PrivateKeyEntry.java: Formatting.
+ (toString): New method.
+ * gnu/javax/crypto/keyring/PasswordEncryptedEntry.java (decrypt):
+ Do not trace/log passwords.
+ Set masked to false before decoding envelope.
+ Do not set payload to null.
+ (encrypt): Set masked to true.
+ * gnu/javax/crypto/keyring/PasswordAuthenticatedEntry.java (verify):
+ Do not trace/log passwords.
+ Set masked to false before decoding envelope.
+ Do not set payload to null.
+ Added trace/debug statements.
+ (authenticate): Do not trace/log passwords.
+ Set masked to true.
+ Added trace/debug statements.
+ (getMac): Added trace/debug statements.
+ * gnu/javax/crypto/keyring/MaskableEnvelopeEntry.java
+ (remove(String)): Changed the signature to return a boolean.
+ (toString): New method.
+ * gnu/javax/crypto/keyring/GnuPublicKeyring.java (containsCertificate):
+ Formatting
+ (getCertificate): Likewise.
+ (putCertificate): Likewise.
+ (load): Likewise.
+ Do not trace/log passwords.
+ (store): Likewise.
+ * gnu/javax/crypto/keyring/GnuPrivateKeyring.java (getPrivateKey):
+ Do not trace/log passwords.
+ Added more trace/logging statements.
+ (putPrivateKey): Do not trace/log passwords.
+ Trace only key's class name.
+ Formatting.
+ (containsPublicKey): Formatting.
+ (getPublicKey): Likewise.
+ Trace only key's class name.
+ (putPublicKey): Trace only key's class name.
+ (containsCertPath): Formatting.
+ (getCertPath): Likewise.
+ (putCertPath): Likewise.
+ (load): Do not trace/log passwords.
+ Formatting.
+ (store): Likewise.
+ * gnu/javax/crypto/keyring/EnvelopeEntry.java (log): New field.
+ (add): Do not set payload to null.
+ Added trace/debug statements.
+ (containsAlias): Added trace/debug statements.
+ (get): Likewise.
+ (remove(Entry)): Likewise.
+ (remove(String)): Likewise.
+ Changed the signature to return a boolean.
+ Do not set payload to null unless really removed.
+ (toString): New method.
+ (decodeEnvelope): Clear entries before proceeding.
+ (makeAliasList): Added trace/debug statements.
+ Ensure only non-null aliases and alias-lists are added.
+ * gnu/javax/crypto/keyring/Entry.java (log): New field.
+ (TYPES): New constant.
+ (toString): New method.
+ (defaultDecode): Add trace/debug statement.
+
+2006-05-20 Raif S. Naffah <raif@swiftdsl.com.au>
+
+ * tools/gnu/classpath/tools/keytool/ListCmd.java (rfc):
+ Increased visibility.
+ (setup): Do not trace/log passwords.
+ (parsed): Was not setting correct (rfc) field; fixed.
+ (print1Chain): Formatting.
+ * tools/gnu/classpath/tools/keytool/DeleteCmd.java (setup):
+ Do not trace/log passwords.
+ * tools/gnu/classpath/tools/keytool/ExportCmd.java (setup): Likewise.
+ * tools/gnu/classpath/tools/keytool/GenKeyCmd.java (setup): Likewise.
+ * tools/gnu/classpath/tools/keytool/IdentityDBCmd.java (setup): Likewise.
+ * tools/gnu/classpath/tools/keytool/KeyCloneCmd.java (setup): Likewise.
+ * tools/gnu/classpath/tools/keytool/StorePasswdCmd.java (setup): Likewise.
+ * tools/gnu/classpath/tools/keytool/ImportCmd.java (setup): Likewise.
+ (orderChain): Added FIXME.
+ * tools/gnu/classpath/tools/keytool/CertReqCmd.java (setup):
+ Do not trace/log passwords.
+ Removed commented out code.
+ * tools/gnu/classpath/tools/keytool/KeyPasswdCmd.java (setup): Likewise.
+ * tools/gnu/classpath/tools/keytool/SelfCertCmd.java (setup): Likewise.
+ * tools/gnu/classpath/tools/keytool/Command.java (doCommand): Formatting.
+ (setKeystoreURLParam): Likewise.
+ (setKeystorePasswordParam): Do not trace/log passwords.
+ (saveKeyStore): Likewise.
+
+2006-05-19 Roman Kennke <kennke@aicas.com>
+
+ * gnu/java/awt/java2d/AbstractGraphics2D.java
+ Added class docs.
+ (pixel): Removed obsolete field.
+ (draw(Shape)): Removed commented out code.
+ (drawImage): Formatting.
+ (drawString): Added optimization hook.
+ (setPaint): Removed rawSetForeground().
+ (getFontRenderContext): Return context with correct transform.
+ (drawGlyphVector): Draw complete outline in one go.
+ (copyArea): Added optimization hook.
+ (clearRect): Added optimization hook.
+ (drawImage): Added optimization hook.
+ (fillShape): (Temporarily) Set antialiasing off by default for
+ font rendering. Adjust the shape by some bits to improve rendering.
+ Pass clip bounds to the render methods.
+ (drawPixel): Removed.
+ (rawSetPixel): Removed.
+ (rawSetForeground): Removed.
+ (rawDrawLine): Default impl calls standard pipeline.
+ (rawDrawString): New method, calls standard pipeline for rendering.
+ (rawClearRect): New method, calls standard pipeline for rendering.
+ (rawFillRect): New method, calls standard pipeline for rendering.
+ (rawDrawImage): New method, calls standard pipeline for rendering.
+ (rawCopyArea): New method.
+ (copyAreaImpl): New method.
+ (rawFillShape): Renamed to fillShapeImpl(). Small optimization
+ for rendering.
+ (fillShapeAntialias): Fixed AA rendering.
+ (fillScanlineAA): Fixed AA rendering.
+ (getSegments): Take offset into account.
+
+2006-05-19 Sven de Marothy <sven@physto.se>
+
+ * javax/swing/text/AbstractWriter.java
+ (getText): Fix parameters (start, length) not (start, end).
+
+2006-05-19 Tom Tromey <tromey@redhat.com>
+
+ PR classpath/27444:
+ * gnu/java/net/loader/URLLoader.java (getClassPath): Documented.
+ Changed return type.
+ * java/net/URLClassLoader.java (urlloaders): Removed.
+ (addURLImpl): Updated.
+ * gnu/java/net/loader/JarURLLoader.java (initialized): New field.
+ (indexSet): Likewise.
+ (classPath): Changed type.
+ (JarURLLoader): New constructor.
+ (initialize): New method.
+ (getResource): Use index set if it exists.
+ (getClassPath): Updated.
+ * gnu/java/net/IndexListParser.java (IndexListParser): Avoid NPE.
+ (prefixes): New field.
+ (headers): Removed.
+ (IndexListParser): Fill in prefixes.
+ (clearAll): Clear prefixes.
+ (getHeaders): Changed return type.
+
+2006-05-19 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/plaf/basic/BasicTableHeaderUI.java
+ (MouseInputHandler.mouseExitted): No nothing there.
+ (MouseInputHandler.endDragging): Move column to the
+ first/last position if released outside the horizontal
+ table range.
+
+2006-05-19 Lillian Angel <langel@redhat.com>
+
+ * java/awt/font/GlyphVector.java
+ (getGlyphCharIndex): Implemented.
+ (getGlyphCharIndices): Implemented.
+ (getGlyphOutline): Implemented.
+ (getGlyphVisualBounds): Implemented.
+ (getGlyphVisualBounds): Implemented.
+ (getPixelBounds): Implemented.
+ (getLayoutFlags): Implemented.
+
+2006-05-19 Robert Schuster <robertschuster@fsfe.org>
+
+ * java/awt/LightweightDispatcher.java: Added field dragButton and
+ documentation for it.
+ (handleMouseEvent): Rewritten MOUSE_PRESSED case in switch-statement,
+ added subexpression to if-clause in MOUSE_RELEASED case.
+
+2006-05-19 Robert Schuster <robertschuster@fsfe.org>
+
+ * javax/swing/metal/MetalButtonUI.java:
+ (update): Removed some subexpression from if-clause and call
+ updateWithGradient.
+ (updateWithGradient): New method.
+
+2006-05-19 Roman Kennke <kennke@aicas.com>
+
+ * javax/swing/JComponent.java
+ (findOverlapFreeParent): Implemented algorithm for finding
+ overlapping in component hierarchy.
+
+2006-05-19 Jeroen Frijters <jeroen@frijters.net>
+
+ * java/lang/Thread.java
+ (contextClassLoaderIsSystemClassLoader): New field.
+ (Thread(ThreadGroup,Runnable)): Call createAnonymousThreadName.
+ (Thread(VMThread,String,int,boolean)): Call createAnonymousThreadName
+ and set contextClassLoaderIsSystemClassLoader.
+ (Thread(ThreadGroup,Runnable,String,long)):
+ Set contextClassLoaderIsSystemClassLoader.
+ (createAnonymousThreadName): New method.
+ (getContextClassLoader): Check contextClassLoaderIsSystemClassLoader
+ and fixed security check.
+ (setContextClassLoader): Clear contextClassLoaderIsSystemClassLoader.
+
+2006-05-19 Robert Schuster <robertschuster@fsfe.org>
+
+ * javax/swing/plaf/basic/BasicToolBarUI.java:
+ (createNonRolloverBorder): Rewritten.
+ (createRolloverBorder): Rewritten.
+ (setToNonRolloverBorder): Store old border instance in hashtable.
+ (setToRolloverBorder): Store old border instance in hashtable, use
+ AbstractButton instead of JButton in statements.
+ (setBorderToNormal): Rewritten.
+ * javax/swing/plaf/metal/MetalLookAndFeel.java:
+ (initComponentDefaults): Added values for ToolBar.rolloverBorder and
+ ToolBar.nonrolloverBorder.
+
+2006-05-18 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * javax/imageio/stream/ImageInputStreamImpl.java: Complete.
+ * javax/imageio/stream/MemoryCacheImageInputStream.java: Likewise.
+
+2006-05-18 Lillian Angel <langel@redhat.com>
+
+ * java/awt/font/GlyphMetrics.java
+ (getLSB): Implemented.
+ (getRSB): Implemented.
+
+2006-05-18 Lillian Angel <langel@redhat.com>
+
+ * java/awt/font/GraphicAttribute.java:
+ Documented entire class.
+ (GraphicAttribute): Added check for alignment.
+ (getBounds): Implemented.
+ (getJustificationInfo): Implemented.
+
+2006-05-18 Robert Schuster <robertschuster@fsfe.org>
+
+ * java/awt/LightweightDispatcher.java:
+ (handleMouseEvent): Added note, added subexpression to if-statement.
+
+2006-05-18 Robert Schuster <robertschuster@fsfe.org>
+
+ * javax/swing/plaf/basic/BasicToolBarUI.java:
+ (navigateFocusedComp): Marked as stub.
+ (createRolloverBorder): Create a different Border instance, added note.
+ * javax/swing/plaf/metal/MetalBorders.java:
+ (ButtonBorder): Added documentation.
+ (ButtonBorder.paintDefaultButtonBorder): Added else-block.
+ (ButtonBorder.paintOceanButtonBorder): Added else-block, added
+ subexpression into if-else cascade, added note.
+
+2006-05-18 Lillian Angel <langel@redhat.com>
+
+ * java/awt/font/ShapeGraphicAttribute.java:
+ Documented entire class.
+ (ShapeGraphicAttribute): Initialized bounds field.
+ (draw): Implemented.
+ (equals): Implemented.
+ (getAdvance): Implemented.
+ (getAscent): Implemented.
+ (getBounds): Implemented.
+ (getDescent): Implemented.
+ (hashCode): Implemented.
+
+2006-05-18 Roman Kennke <kennke@aicas.com>
+
+ * javax/swing/CellRendererPane.java
+ (CellRendererPane): Set CellRendererPane to invisible.
+
+2006-05-18 Roman Kennke <kennke@aicas.com>
+
+ * gnu/java/awt/peer/gtk/GdkGraphics.java
+ (clipRect): Removed old intersection statement.
+
+2006-05-18 Roman Kennke <kennke@aicas.com>
+
+ * gnu/java/awt/peer/gtk/GdkGraphics.java
+ (clipRect): Don't use Rectangle.intersection() to avoid creating
+ 2 unnecessary Rectangle instances and fix a clipping problem.
+ (computeIntersection): New helper method, adapted from SwingUtilities.
+
+2006-05-18 Roman Kennke <kennke@aicas.com>
+
+ * javax/swing/JComponent.java
+ (isCompletelyDirty): Removed.
+ (paint): Don't mark children as clean, this is no longer necessary.
+ (findOverlapFreeParent): Don't stop at Viewports, this breaks
+ painting when something overlaps the viewport (like a popup/menu).
+ * javax/swing/RepaintManager.java
+ (currentRepaintManagers): Made package private to avoid accessor
+ methods.
+ (dirtyComponents): Made private.
+ (dirtyComponentsWork): Made private.
+ (markCompletelyDirty): Fixed bounds of dirtyrect to be
+ component-local not parent-local. Do not set flag in JComponent.
+ (markCompletelyClean): Don't set JComponent flag.
+ (isCompletelyDirty): Rewritten to return true when the complete
+ component is marked dirty.
+ (paintDirtyRegions): Improved parent-merging so that the merged-in
+ components don't get painted too. 'Outsourced' the compilation
+ of the repaint root components.
+ (compileRepaintRoots): New helper method.
+
+2006-05-18 Roman Kennke <kennke@aicas.com>
+
+ PR 26368
+ * javax/swing/text/GapContent.java
+ (GapContentPosition(int)): Use adapted binarySearch method to
+ allow for having a greater array than number of entries.
+ (numMarks): New field, holds the end of the marks list.
+ (GapContent): Initialize positionMarks with size of 10 instead of 0.
+ (shiftGapStartDown): Adjusted for new setPositionsInRange signature.
+ (shiftGapEndUp): Adjusted for new setPositionsInRange signature.
+ (setPositionsInRange): Changed signature to narrow the purpose and
+ special cases inside. Reimplemented to crunch together equal marks.
+ (adjustPositionsInRange): Added assertion to make sure we do
+ not accidentally change the order of the mark. Added some debug
+ output for a special case of which I don't know if it even exists.
+ (resetMarksAtZero): Made impl simpler.
+ (dumpMarks): New debug helper method.
+ (insertMark): Grow array in bigger chunks to avoid excessive copying.
+ (binarySearch): New method. An adaption of Arrays.binarySearch()
+ that allows for an maxIndex parameter.
+
+2006-05-18 Roman Kennke <kennke@aicas.com>
+
+ * javax/swing/KeyboardManager.java
+ (topLevelLookup): Use WeakHashMap to avoid memory leak.
+
+2006-05-18 Jeroen Frijters <jeroen@frijters.net>
+
+ * gnu/java/net/loader/JarURLLoader.java
+ (JarURLLoader): Use a slightly more efficient URL constructor.
+
+2006-05-18 David Gilbert <david.gilbert@object-refinery.com>
+
+ * gnu/java/awt/print/JavaPrinterGraphics.java
+ (drawImage(Image, int, int, Color, ImageObserver)): Fix endless loop,
+ (drawImage(Image, int, int, ImageObserver)): Likewise,
+ (drawImage(Image, int, int, int, int, Color, ImageObserver)): Likewise,
+ (drawImage(Image, int, int, int, int, ImageObserver)): Likewise,
+ (drawImage(Image, int, int, int, int, int, int, int, int, Color,
+ ImageObserver)): Likewise,
+ (drawImage(Image, int, int, int, int, int, int, int, int,
+ ImageObserver)): Likewise.
+
+2006-05-17 Tom Tromey <tromey@redhat.com>
+
+ * tools/gnu/classpath/tools/jar/Indexer.java (indexJarFile): Use a
+ LinkedHashSet.
+
+2006-05-17 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/border/AbstractBorder.java: Source code formatting fixes,
+ * javax/swing/border/BevelBorder.java: Likewise,
+ * javax/swing/border/CompoundBorder.java: Likewise,
+ * javax/swing/border/TitledBorder.java: Likewise.
+
+2006-05-17 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/table/AbstractTableModel.java: Formatting fixes,
+ * javax/swing/table/DefaultTableModel.java: Likewise,
+ * javax/swing/table/TableCellEditor.java: Likewise,
+ * javax/swing/table/TableCellRenderer.java: Likewise.
+
+2006-05-17 Lillian Angel <langel@redhat.com>
+
+ * java/awt/font/ImageGraphicAttribute.java:
+ Documented entire class.
+ (ImageGraphicAttribute): Changed to call this.
+ (ImageGraphicAttribute): Implemented.
+ (draw): Implemented.
+ (equals): Implemented.
+ (getAdvance): Implemented.
+ (getAscent): Implemented.
+ (getBounds): Implemented.
+ (getDescent): Implemented.
+ (hashCode): Implemented.
+ * javax/swing/text/html/HTMLDocument.java
+ (create): Removed. Sufficent enough for
+ super to be called.
+ (insert): Likewise.
+ (insertUpdate): Likewise.
+ (processHTMLFrameHyperlinkEvent): Marked as stub.
+ (start): Removed FIXME.
+ (end): Likewise.
+ (start): Called super.
+ (end): Called super.
+ (getElement): removed unneeded code.
+ (setParagraphAttribute): Removed. Sufficent enough
+ for super to be called.
+ (fireChangedUpdate): Likewise.
+ (fireUndoableEditUpdate): Likewise.
+
+2006-05-17 Lillian Angel <langel@redhat.com>
+
+ * java/awt/TexturePaint.java:
+ Added documentation for class and all functions.
+ (getTransparency): Implemented.
+
+2006-05-17 Roman Kennke <kennke@aicas.com>
+
+ * java/awt/LightweightDispatcher.java
+ (findTarget): Translate point to child components.
+
+2006-05-17 Roman Kennke <kennke@aicas.com>
+
+ PR 26368
+ * javax/swing/text/GapContent.java
+ (GapContentPosition): Do no more implement Comparable.
+ (GapContentPosition.mark): Removed field.
+ (GapContentPosition.index): New field to hold the index into
+ the positions array.
+ (GapContentPosition(int)): Rewritten to use the new indirection
+ to the positions array.
+ (GapContentPosition.compareTo): Removed.
+ (GapContentPosition.getOffset): Synchronized. Fetch mark from
+ positionMarks array.
+ (WeakPositionComparator): Removed obsolete class.
+ (positions): Changed type to WeakHashMap.
+ (positionMarks): New field, holds the marks of the positions.
+ (GapContent): Initialize new fields.
+ (createPosition): Rewritten to use the new indirection
+ to the positions array.
+ (getPositionsInRange): Rewritten to use the new indirection
+ to the positions array.
+ (setPositionsInRange): Rewritten to use the new indirection
+ to the positions array.
+ (adjustPositionsInRange): Rewritten to use the new indirection
+ to the positions array.
+ (insertMark): New helper method.
+ (clearPositionReferences): Removed obsolete methods.
+
+2006-05-17 Lillian Angel <langel@redhat.com>
+
+ * java/awt/GraphicsConfiguration.java
+ (getImageCapabilities): Implemented.
+ (getBufferCapabilities): Implemented.
+
+2006-05-17 Lillian Angel <langel@redhat.com>
+
+ * javax/swing/plaf/basic/BasicSliderUI.java
+ (focusGained): Implemented.
+ (focusLost): Implemented.
+ (paint): Added code to paint the focus.
+ * javax/swing/plaf/metal/MetalSliderUI.java
+ (paintThumb): Added code to set the thumbColor.
+ (paintFocus): Implemented properly.
+
+2006-05-17 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ PR 27383
+ * javax/naming/spi/NamingManager.java (getURLContext):
+ Always search for the factory class in all possible places
+ and use VMStackWalker.
+ (forName): New method.
+
+2006-05-17 Roman Kennke <kennke@aicas.com>
+
+ * java/awt/LightweightDispatcher.java
+ (handleMouseEvent): Fixed search algorithm for finding the
+ mouse event target.
+ (findTarget): Fixed search algorithm for finding the
+ mouse event target.
+
+2006-05-17 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/naming/spi/NamingManager.java: Documented.
+
+2006-05-17 Mark Wielaard <mark@klomp.org>
+
+ * THANKYOU: Add Trevor Linton <tlinton@xmission.com>.
+ * gnu/javax/imageio/jpeg/DCT.java: Cleanup Todo copyright.
+ * gnu/javax/imageio/jpeg/YCbCr_ColorSpace.java: Likewise.
+ * gnu/javax/imageio/jpeg/ZigZag.java: Likewise.
+
+2006-05-17 Robert Schuster <robertschuster@fsfe.org>
+
+ Fixes PR 26947.
+ * javax/swing/plaf/basic/BasicInternalFrameUI.java: Updated copyright
+ year.
+ (BorderListener.mouseClicked): Detect double-clicks in title pane,
+ copied code from
+ BasicInternalFrameTitlePaneUI.MaximizeAction.actionPerformed().
+
+2006-05-17 Robert Schuster <robertschuster@fsfe.org>
+
+ Fixes PR 27626.
+ * java/awt/LightweightDispatcher.java:
+ (handleMouseEvent): Moved assignment into switch-block, added notes.
+
+2006-05-16 Lillian Angel <langel@redhat.com>
+
+ * javax/swing/text/StyleContext.java:
+ Changed staticAttributeKeys to be a Hashtable.
+ (getStaticAttribute): Implemented.
+ (getStaticAttributeKey): Implemented.
+ (readAttributeSet): Implemented.
+ (writeAttributeSet): Added FIXME. Not sure how
+ to implement this.
+ (readAttributes): Implemented.
+ (writeAttributes): Implemented.
+ (registerStaticAttibuteKey): Fixed to add key to
+ the hash table.
+
+2006-05-16 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/DefaultButtonModel.java
+ (setGroup): Removed event notification.
+
+2006-05-16 Lillian Angel <langel@redhat.com>
+
+ * javax/swing/plaf/basic/BasicComboBoxUI.java
+ (installKeyboardActions): Implemented.
+ (uninstallKeyboardActions): Implemented.
+ * javax/swing/plaf/basic/BasicComboPopup.java
+ (uninstallKeyboardActions): Removed FIXME. Nothing
+ to be done here.
+ (installKeyboardActions): Likewise.
+ * javax/swing/plaf/basic/BasicTextUI.java
+ (uninstallKeyboardActions): Implemented.
+ * javax/swing/plaf/basic/BasicTreeUI.java:
+ Added field for hashColor.
+ Marked stub methods.
+ (getHashColor): Implemented to use field.
+ (setHashColor): Likewise.
+ (getRowX): Implemented.
+ (NodeDimensions.getRowX): Changed to use BasicTreeUI.getRowX.
+
+2006-05-16 Roman Kennke <kennke@aicas.com>
+
+ PR 26521
+ * javax/swing/JTable.java
+ (rowHeights): New field.
+ (initializeLocalVars): Call setRowHeigt instead of rowHeight=,
+ in order to initialize rowHeights correctly.
+ (tableChanged): Nullify rowHeights when model changes. Only
+ create default columns from model when corresponding property
+ is set. Sync table model with rowHeights as appropriate.
+ (valueChanged): Call repaint with the correct rectangle.
+ (rowAtPoint): Handle rowHeights.
+ (getCellRect): Mostly rewritten. Check for boundaries
+ of model and return (0,0,0,0) or (0,0,width,height) when outside.
+ Handle component orientation. Round correctly.
+ (getRowHeight(int)): Implemented for variable row height.
+ (setRowHeight(int,int)): Implemented for variable row height.
+ (setRowHeight(int)): Nullify rowHeights.
+ (setModel): Notify tableChanged().
+ * javax/swing/plaf/basic/BasicTableUI.java
+ (installDefaults): Create rendererPane in installUI.
+ (installUI): Create and install rendererPane.
+ (uninstallUI): Uninstall rendererPane and nullify rendererPane
+ and table.
+ (paint): Correctly handle rowMargin.
+
+2006-05-16 Tom Tromey <tromey@redhat.com>
+
+ PR classpath/27563:
+ * java/text/NumberFormat.java (getIntegerInstance): Use
+ "integerFormat", not "numberFormat".
+
+2006-05-16 Lillian Angel <langel@redhat.com>
+
+ * javax/swing/JPopupMenu.java
+ (addMenuKeyListener): Implemented.
+ (removeMenuKeyListener): Implemented.
+ (getMenuKeyListeners): Implemented.
+ * javax/swing/ProgressMonitor.java:
+ Added new protected field.
+ (getAccessibleContext): Implemented.
+
+2006-05-16 Lillian Angel <langel@redhat.com>
+
+ * javax/swing/JFileChooser.java:
+ Added new private field.
+ (setDragEnabled): Implemented.
+ (getDragEnabled): Implemented.
+
+2006-05-16 Lillian Angel <langel@redhat.com>
+
+ * java/awt/Window.java
+ (applyResourceBundle): Implemented.
+
+2006-05-16 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/DefaultButtonModel.java
+ (setSelected): If new SELECTED state is false, clear ARMED and PRESSED
+ states also.
+
+2006-05-16 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/JList.java (getSelectedValues):
+ Ask the value for the indexed array element.
+
+2006-05-16 Roman Kennke <kennke@aicas.com>
+
+ * javax/swing/JTable.java
+ (valueChanged): Also repaint when table has only 1 row. Fixed
+ repaint rectangle to span the entire changed rows.
+
+2006-05-16 Roman Kennke <kennke@aicas.com>
+
+ PR 24031
+ * javax/swing/JOptionPane.java
+ (startModal): Rewritten. The events are now dispatched, even
+ when the event dispatch thread gets blocked by the call
+ to this method. Also, mouse events get intercepted outside the
+ internal frame.
+
+2006-05-16 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/plaf/basic/BasicInternalFrameUI.java
+ (BorderListener.mouseDragged):Do not set cursor
+ if the frame is being dragged.
+
+2006-05-16 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/plaf/basic/BasicInternalFrameUI.java
+ (BorderListener): Rewritten. (InternalFrameBorder):
+ Made package private.
+ (InternalFrameBorder.offset):
+ Renamed to cornerSize, made package private.
+ (bSize): Made package private.
+
+2006-05-16 Roman Kennke <kennke@aicas.com>
+
+ * javax/swing/JMenu.java
+ (AccessibleJMenu.getAccessibleChildrenCount): Implemented.
+ (AccessibleJMenu.getAccessibleChild): Implemented.
+ (AccessibleJMenu.getAccessibleSelection): Implemented.
+ (AccessibleJMenu.getAccessibleSelection(int)): Implemented.
+ (AccessibleJMenu.isAccessibleChildSelected): Implemented.
+ (AccessibleJMenu.getAccessibleRole): Documented.
+ (AccessibleJMenu.getAccessibleSelectionCount): Implemented.
+ (AccessibleJMenu.addAccessibleSelection): Implemented.
+ (AccessibleJMenu.removeAccessibleSelection): Implemented.
+ (AccessibleJMenu.clearAccessibleSelection): Implemented.
+ (AccessibleJMenu.selectAllAccessibleSelection): Implemented.
+ (createPath): New helper method.
+
+2006-05-15 Tom Tromey <tromey@redhat.com>
+
+ * java/net/URLClassLoader.java: Moved inner classes to
+ gnu.java.net.loader.
+ (factoryCache): Changed type.
+ (URL_LOADER_PREFIX): New constant.
+ (URLClassLoader): Updated for new factoryCache.
+ (addURLImpl): Use reflection to search for a loader.
+ (findClass): Use getClass method on URLLoader.
+ (getURLStreamHandler): Removed.
+ * gnu/java/net/loader/URLLoader.java: New file, extracted
+ from URLClassLoader.
+ * gnu/java/net/loader/Resource.java: Likewise.
+ * gnu/java/net/loader/FileResource.java: Likewise.
+ * gnu/java/net/loader/FileURLLoaderjava: Likewise.
+ * gnu/java/net/loader/JarURLLoader.java: Likewise.
+ * gnu/java/net/loader/JarURLResource.java: Likewise.
+ * gnu/java/net/loader/RemoteURLLoader.java: Likewise.
+ * gnu/java/net/loader/RemoteResource.java: Likewise.
+ * gnu/java/net/loader/ULRStreamHandlerCache.java: New file.
+
+2006-05-15 Sven de Marothy <sven@physto.se>
+
+ * native/target/generic/target_generic_network.h:
+ Add a pair of parenthesis.
+
+2006-05-15 Mark Wielaard <mark@klomp.org>
+
+ * java/awt/Graphics2D.java: Remove PrinterJob import.
+
+2006-05-15 Mark Wielaard <mark@klomp.org>
+
+ * doc/www.gnu.org/announce/20060515.wml: New file.
+ * doc/www.gnu.org/newsitems.txt: Add 0.91 release announcement.
+ * doc/www.gnu.org/downloads/downloads.wml: Add 0.91.
+
+2006-05-15 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * NEWS: Announce inclusion of gcjwebplugin.
+ Announce inclusion of appletviewer.
+ * INSTALL: Note gcjwebplugin dependencies.
+
+2006-05-15 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/RepaintManager.java (paintDirtyRegions):
+ Break loop as soon as the component repaint is merged
+ with some parent. (ComponentComparator): Removed.
+ (comparator): Removed.
+
+2006-05-15 Roman Kennke <kennke@aicas.com>
+
+ * javax/swing/border/TitledBorder.java
+ (paintBorderWithTitle): Fixed indentation.
+
+2006-05-15 Roman Kennke <kennke@aicas.com>
+
+ * javax/swing/border/TitledBorder.java
+ (layoutBorderWithTitle): Fetch border using getBorder() instead
+ of using the border field directly. Allows for the use of
+ an UI supplied border in the case when a null border was set.
+ Fixed component orientation.
+ (paintBorderWithTitle): Fetch border using getBorder() instead
+ of using the border field directly. Allows for the use of
+ an UI supplied border in the case when a null border was set.
+
+2006-05-15 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/RepaintManager.java (paintDirtyRegions): Rewritten.
+ (contains): New method.
+
+2006-05-15 Tom Tromey <tromey@redhat.com>
+
+ * resource/gnu/classpath/tools/jar/messages.properties: Fixed
+ argument indices.
+ * resource/gnu/classpath/tools/getopt/Messages.properties: Fixed
+ argument indices.
+
+2006-05-15 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/JComponent.java (findOverlapParent): Stop loop at
+ JViewport's.
+ * javax/swing/RepaintManager.java (addDirtyRegion): Always add the given
+ region. (paintDirtyRegions): Rewritten.
+
+2006-05-15 Tom Tromey <tromey@redhat.com>
+
+ * tools/gnu/classpath/tools/jar/Main.java (setArchiveFile): Use
+ MessageFormat.
+ * tools/gnu/classpath/tools/jar/Indexer.java (indexJarFile): Use
+ MessageFormat.
+ * tools/gnu/classpath/tools/jar/Extractor.java: Externalized strings.
+ (run): Use MessageFormat.
+ * resource/gnu/classpath/tools/jar/messages.properties: New file.
+ * tools/gnu/classpath/tools/jar/Creator.java: Externalized strings.
+ (writeFile): Use MessageFormat.
+
+2006-05-15 Jeroen Frijters <jeroen@frijters.net>
+
+ * java/awt/Toolkit.java (getDefaultToolkit): Use Class.forName()
+ instead of directly calling the class loader.
+
+2006-05-15 Tom Tromey <tromey@redhat.com>
+
+ * tools/gnu/classpath/tools/getopt/Option.java (getDescription):
+ Removed old comment.
+ * tools/gnu/classpath/tools/getopt/ClasspathToolParser.java:
+ Externalized strings.
+ (getVersionString): Use MessageFormat.
+ * tools/gnu/classpath/tools/getopt/Messages.java: New file.
+ * resource/gnu/classpath/tools/getopt/Messages.properties: New file.
+ * tools/gnu/classpath/tools/getopt/Parser.java: Externalized strings.
+ (getArgument): Use a MessageFormat.
+ (handleLongOption): Likewise.
+ (parse): Likewise.
+
+2006-05-15 Robert Schuster <robertschuster@fsfe.org>
+
+ Fixes PR 27197.
+ * javax/swing/text/FieldView.java:
+ (paint): Calculate intersection between clip and allocation area and
+ set that as new clip.
+
+2006-05-15 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/text/JTextComponent.java: Marked stub methods.
+
+2006-05-15 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JTable.java: Marked stub methods.
+
+2006-05-15 Raif S. Naffah <raif@swiftdsl.com.au>
+
+ * tools/gnu/classpath/tools/jarsigner/Main.java:
+ Increased visibility of fields used by parser anonymous classes.
+ (KEYTOOL_TOOL): New constant.
+ (cmdLineParser): Changed type to ToolParser.
+ (fileAndAlias): new field.
+ (main): Don't catch OptionException.
+ (processArgs): Removed validation checks; now handled by ToolParser.
+ (getParser): Removed.
+ (ToolParserCallback): New inner class.
+ (ToolParser): Likewise.
+
+2006-05-15 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/JTable.java (TableTextArea.scrollRectToVisible):
+ Removed.
+
+2006-05-15 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/DefaultDesktopManager.java (endDraggingFrame,
+ endResizingFrame): Do not repaint, unless in the outline mode.
+
+2006-05-15 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JTabbedPane.java
+ (AccessibleJTabbedPane.getAccessibleRole): Implemented,
+ (AccessibleJTabbedPane.getAccessibleChildrenCount): Implemented,
+ (AccessibleJTabbedPane.getAccessibleSelection()): Implemented,
+ (AccessibleJTabbedPane.getAccessibleAt): Implemented,
+ (AccessibleJTabbedPane.getAccessibleSelectionCount): Implemented,
+ (AccessibleJTabbedPane.getAccessibleSelection(int)): Implemented,
+ (AccessibleJTabbedPane.isAccessibleChildSelected): Implemented,
+ (AccessibleJTabbedPane.addAccessibleSelection): Implemented,
+ (AccessibleJTabbedPane.removeAccessibleSelection): Implemented,
+ (AccessibleJTabbedPane.clearAccessibleSelection): Implemented,
+ (AccessibleJTabbedPane.selectAllAccessibleSelection): Implemented,
+ (Page.getAccessibleName): Implemented.
+
+2006-05-15 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/DefaultDesktopManager.java (setBoundsForFrame):
+ Do not repaint nor revalidate here.
+
+2006-05-15 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/RepaintManager.java (addDirtyRegion):
+ If there is a lightweight parent, recursively add the corresponding
+ region of the parent instead.
+
+2006-05-15 David Gilbert <david.gilbert@object-refinery.com>
+
+ * java/awt/Graphics2D.java: Added some API doc comments.
+
+2006-05-15 Mark Wielaard <mark@klomp.org>
+
+ * NEWS: Add release date and VMClassLoader.getBootPackages()
+ changes.
+
+2006-05-15 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JTabbedPane.java
+ (paramString): Reimplemented,
+ (getAccessibleContext): Added API docs.
+
+2006-05-15 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JFileChooser.java
+ (paramString): Reimplemented,
+ (getAccessibleContext): Updated API docs,
+ (AccessibleJFileChooser): Added API docs.
+
+2006-05-14 Tom Tromey <tromey@redhat.com>
+
+ * tools/gnu/classpath/tools/jar/Updater.java (run): No longer throws
+ OptionException.
+ * tools/gnu/classpath/tools/jar/Creator.java (run): No longer throws
+ OptionException.
+ * tools/gnu/classpath/tools/jar/Action.java (run): No longer throws
+ OptionException.
+ * tools/gnu/classpath/tools/jar/Indexer.java (run): Removed. Moved
+ validation to JarParser.
+ * tools/gnu/classpath/tools/jar/Main.java (JarParser): New class.
+ (run): Moved validation to JarParser. Don't throw OptionException.
+ (initializeParser): Create a JarParser.
+ (main): Don't catch OptionException.
+ * tools/gnu/classpath/tools/getopt/Parser.java (printHelp): No longer
+ public.
+ (validate): New method.
+ (parse): Call it. Print '-help' in error message when long-only.
+
+2006-05-14 Tom Tromey <tromey@redhat.com>
+
+ * gnu/java/awt/print/JavaPrinterJob.java (setPrintable): Fixed
+ assignment.
+
+2006-05-15 Sven de Marothy <sven@physto.se>
+
+ * gnu/java/awt/print/JavaPrinterGraphics.java:
+ Sweeping changes I can't be bothered to document in detail.
+ * gnu/java/awt/print/JavaPrinterJob.java
+ (getPageAttributes): New method.
+ (setPageable,cancel,isCancelled): Implement.
+
+2006-05-15 Christian Thalinger <twisti@complang.tuwien.ac.at>
+
+ * README: Added CACAO to list of VMs.
+
+2006-05-14 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JCheckBoxMenuItem.java
+ (requestFocus): Fixed typo in API docs,
+ (paramString): Just call super.paramString(),
+ (getAccessibleContext): Added API docs,
+ (AccessibleJCheckBoxMenuItem): Likewise.
+
+2006-05-14 Tom Tromey <tromey@redhat.com>
+
+ * tools/gnu/classpath/tools/jar/Indexer.java
+ (writeCommandLineEntries): Simplify insertion.
+ * tools/gnu/classpath/tools/jar/Main.java (run): Don't allow both
+ -m and -M.
+
+2006-05-14 Tom Tromey <tromey@redhat.com>
+
+ PR classpath/27514:
+ * gnu/java/net/IndexListParser.java (JAR_INDEX_FILE): Renamed. Now
+ constant.
+ (JAR_INDEX_VERSION_KEY): Likewise.
+ (IndexListParser): Updated.
+ (getVersionInfo): Likewise.
+ * tools/gnu/classpath/tools/jar/Indexer.java: New file.
+ * tools/gnu/classpath/tools/jar/Action.java (run): Now throws
+ OptionException.
+ * tools/gnu/classpath/tools/jar/Main.java (initializeParser): Handle
+ -i.
+ (ModeOption): New constructor.
+ (parsed): Updated. Use setArchiveFile.
+ (setArchiveFile): New method.
+ (run): Handle no-argument case.
+ (main): Emit --help message on option error.
+ * tools/gnu/classpath/tools/jar/Updater.java (inputJar): New field.
+ (createManifest): New method.
+ (run): Updated. Throws OptionException. Correctly copy zip entry.
+ * tools/gnu/classpath/tools/jar/Creator.java (createManifest): New
+ method.
+ (writeManifest): Removed.
+ (outputStream): Now a JarOutputStream.
+ (writeCommandLineEntries): Changed parameters. Updated callers.
+ (run): Throws OptionException.
+ * java/util/jar/JarOutputStream.java (putNextEntry): Typo fix.
+ * java/util/jar/Manifest.java (read): Typo fix.
+
+2006-05-14 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JMenuItem.java
+ (paramString): Fixed class name in API doc comment.
+
+2006-05-14 Tom Tromey <tromey@redhat.com>
+
+ * native/plugin/.cvsignore: Updated.
+
+2006-05-14 Mark Wielaard <mark@klomp.org>
+
+ * native/jni/java-net/javanet.c (_javanet_accept): Don't use C++
+ comments.
+
+2006-05-14 Mark Wielaard <mark@klomp.org>
+
+ PR 27459
+ * native/jni/java-net/javanet.c (_javanet_accept): Reset the
+ inherited timeout on socket.
+
+2006-05-14 Raif S. Naffah <raif@swiftdsl.com.au>
+
+ * tools/gnu/classpath/tools/jarsigner/Main.java (main): Formatting.
+
+2006-05-14 Raif S. Naffah <raif@swiftdsl.com.au>
+
+ * resource/gnu/classpath/tools/keytool/MessageBundle.properties:
+ Added help text.
+ * tools/gnu/classpath/tools/keytool/keytool.txt: Removed
+ * tools/gnu/classpath/tools/keytool/StorePasswdCmd.java:
+ Increased visibility of fields used by parser anonymous classes.
+ (processArgs): Removed.
+ (getParser): New method.
+ * tools/gnu/classpath/tools/keytool/SelfCertCmd.java: Likewise.
+ (setup): Mark (Eclipse) strings that need not be externalised.
+ (start): Likewise.
+ * tools/gnu/classpath/tools/keytool/PrintCertCmd.java: Likewise.
+ * tools/gnu/classpath/tools/keytool/Main.java: Amended to use getopt
+ command line option parsing.
+ * tools/gnu/classpath/tools/keytool/ListCmd.java:
+ Increased visibility of fields used by parser anonymous classes.
+ (processArgs): Removed.
+ (setup): set 'all' local field.
+ (getParser): New method.
+ * tools/gnu/classpath/tools/keytool/KeyPasswdCmd.java:
+ Increased visibility of fields used by parser anonymous classes.
+ (processArgs): Removed.
+ (getParser): New method.
+ * tools/gnu/classpath/tools/keytool/KeyCloneCmd.java: Likewise.
+ (setNewKeyPassword): Fixed comments.
+ * tools/gnu/classpath/tools/keytool/ImportCmd.java:
+ Increased visibility of fields used by parser anonymous classes.
+ (processArgs): Removed.
+ (getParser): New method.
+ (findTrustInCACerts): Mark (Eclipse) strings that need not be
+ externalised.
+ * tools/gnu/classpath/tools/keytool/GenKeyCmd.java:
+ Increased visibility of fields used by parser anonymous classes.
+ (processArgs): Removed.
+ (setup): Mark (Eclipse) strings that need not be externalised.
+ (getParser): New method.
+ * tools/gnu/classpath/tools/keytool/IdentityDBCmd.java: Likewise.
+ * tools/gnu/classpath/tools/keytool/DeleteCmd.java:
+ Increased visibility of fields used by parser anonymous classes.
+ (processArgs): Removed.
+ (getParser): New method.
+ * tools/gnu/classpath/tools/keytool/CertReqCmd.java: Likewise.
+ (ATTRIBUTES_OPT): New constant.
+ * tools/gnu/classpath/tools/keytool/ExportCmd.java:
+ Increased visibility of fields used by parser anonymous classes.
+ (processArgs): Removed.
+ (setup): Mark (Eclipse) strings that need not be externalised.
+ (start): Likewise.
+ Reduced logging level.
+ (getParser): New method.
+ * tools/gnu/classpath/tools/keytool/Command.java
+ (processArgs): Made it concrete.
+ (getParser): New abstract method.
+ * tools/Makefile.am (KEYTOOL_HELPS): Removed.
+
+2006-05-13 Casey Marshall <csm@gnu.org>
+
+ Patch by Michael Barker <mike@middlesoft.co.uk>.
+ * gnu/java/nio/PipeImpl.java: Retrofitted to use VMChannel.
+ * gnu/java/nio/SelectorImpl.java (register): Added condition for
+ gnu.java.nio.SocketChannelSelectionKeyImpl.
+ * gnu/java/nio/SocketChannelSelectionKeyImpl.java: new file.
+ * gnu/java/nio/channels/FileChannelImpl.java: retrofitted to use
+ VMChannel.
+ * include/gnu_java_nio_VMChannel.h: new file.
+ * java/nio/FileChannel.java (read,write): changed to call abstract
+ method.
+ * native/jni/java-nio/gnu_java_nio_VMChannel.c: new file.
+ * native/jni/java-nio/Makefile.am (libjavanio_SOURCES): add
+ `gnu_java_nio_VMChannel.c.'
+ * vm/reference/gnu/java/nio/VMChannel.java: new file.
+
+2006-05-14 Robert Schuster <robertschuster@fsfe.org>
+
+ * javax/swing/text/AbstractDocument.java:
+ (insertString): Flipped if-expression and its blocks.
+ (remove): Dito.
+ (replace): Flipped if-expression and its blocks, added note, invoke
+ insertString and remove instead of insertStringImpl and removeImpl.
+
+2006-05-13 Tom Tromey <tromey@redhat.com>
+
+ * java/nio/ByteBufferImpl.java (compact): Always set position.
+
+2006-05-13 Sven de Marothy <sven@physto.se>
+
+ * gnu/java/awt/print/JavaPrinterGraphics.java
+ (spoolPostScript): Use a faster writer.
+
+2006-05-13 Sven de Marothy <sven@physto.se>
+
+ * gnu/java/awt/print/JavaPrinterGraphics.java
+ (colorTripleHex): Reimplement better.
+
+2006-05-13 Sven de Marothy <sven@physto.se>
+
+ * javax/swing/text/html/HTMLDocument.java
+ (CharacterAction.start): Translate tag to StyleAttribute.
+ (pushCharacterStyle): Push copy of attributes onto stack.
+ * gnu/javax/swing/text/html/CharacterAttributeTranslator.java:
+ New file
+
+2006-05-13 Sven de Marothy <sven@physto.se>
+
+ * gnu/javax/print/ipp/IppRequest.java (send): Set a timeout.
+ * java/awt/print/PrinterJob.java
+ (getPrinterJob): Return a JavaPrinterJob
+ (setPrintService,getPrintService): Implement.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c:
+ (getPixels): Gtk_threads_enter required.
+ * gnu/java/awt/print/JavaPrinterGraphics.java
+ * gnu/java/awt/print/JavaPrinterJob.java
+ * gnu/java/awt/print/SpooledDocumet.java:
+ New files.
+
+2006-05-13 Robert Schuster <robertschuster@fsfe.org>
+
+ * javax/swing/text/TextAction.java:
+ (HorizontalMovementAction): New inner class.
+ (VerticalMovementAction): New inner class.
+ * javax/swing/text/DefaultEditorKit.java: Added assigning instances of
+ new inner classes to array 'defaultActions'.
+ (SelectionBeginWordAction): New inner class.
+ (SelectionEndWordAction): New inner class.
+ (BeginWordAction): New inner class.
+ (EndWordAction): New inner class.
+ (PreviousWordAction.actionPerformed): Rewritten.
+ (SelectLineAction): New inner class.
+ (SelectWordAction): New inner class.
+ (SelectionDownAction): Rewritten.
+ (SelectionUpAction): Rewritten.
+ (DownAction): Rewritten.
+ (UpAction): Rewritten.
+ (SelectionForwardAction): Rewritten.
+ (SelectionBackwardAction): Rewritten.
+ (ForwardAction): Rewritten.
+ (BackwardAction): Rewritten.
+ (BeginAction): New inner class.
+ (EndAction): New inner class.
+ (DefaultKeyTypedAction.actionPerformed): Use int variant of
+ Character.isISOControl.
+
+2006-05-13 Robert Schuster <robertschuster@fsfe.org>
+
+ * examples/gnu/classpath/examples/swing/NavigationFilterDemo.java:
+ (WordFilter.getNextVisualPositionFrom): Added statement to check
+ for variable pt not being null.
+
+2006-05-13 Robert Schuster <robertschuster@fsfe.org>
+
+ * javax/swing/text/Utilities.java:
+ (getNextWord): Fixed grammar in exception message.
+ (getPreviousWord): Changed expression in first if-clause, added sub-
+ expression to if-clause in while-loop.
+ (getWordStart): Changed expression in if-clause.
+ getNextVisualPositionFrom): Added package-private helper method.
+
+2006-05-13 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ * javax/swing/tree/DefaultTreeSelectionModel.java (leadRow):
+ Initialise to -1.
+
+2006-05-13 Raif S. Naffah <raif@swiftdsl.com.au>
+
+ * resource/gnu/classpath/tools/jarsigner/MessageBundle.properties:
+ Added help text.
+ * tools/Makefile.am (JARSIGNER_HELPS): Removed.
+ * tools/gnu/classpath/tools/jarsigner/jarsigner.txt: Removed.
+ * tools/gnu/classpath/tools/jarsigner/Main.java:
+ Increased visibility of fields used by parser anonymous classes.
+ (HELP_PATH): Removed.
+ (cmdLineParser): New field.
+ (main): Handle JVM exit status.
+ Handle command line parsing exceptions.
+ (processArgs): Use getopt command line parser.
+ (getParser): New method.
+ (setupCommonParams): Removed checks now handled by processArgs().
+ (setupSigningParams): Likewise.
+ * tools/gnu/classpath/tools/jarsigner/JarSigner.java (start):
+ Reuse an existing message-bundle constant.
+
+2006-05-12 Tom Tromey <tromey@redhat.com>
+
+ * gnu/java/net/protocol/jar/Connection.java (getHeaderField):
+ Explicitly specify class for synchronization.
+
+2006-05-12 Tom Tromey <tromey@redhat.com>
+
+ * java/util/logging/Logger.java (resetLogger): Fixed typo.
+
+2006-05-12 Sven de Marothy <sven@physto.se>
+
+ * gnu/java/net/protocol/http/HTTPConnection.java (get): Add timeout parameter.
+ * gnu/java/net/protocol/http/HTTPURLConnection.java
+ (setConnectTimeout): New method.
+ (getConnection): Add timeout parameter.
+ * java/net/URLConnection.java
+ (getConnectTimeout, setConnectTimeout): Implement.
+ * native/target/generic/target_generic_network.h:
+ Set correct socket parameters SO_SNDTIMEO and SO_RCVTIMEO.
+
+2006-05-12 Sven de Marothy <sven@physto.se>
+
+ * gnu/javax/print/CupsServer.java
+ (CupsServer): Make the Cups host configurable.
+ * java/lang/System.java: Document the system property.
+
+2006-05-12 Roman Kennke <kennke@aicas.com>
+
+ * javax/swing/border/TitledBorder.java
+ (paintBorder): Rewritten for simplicity and correctness.
+ (layoutBorderWithTitle): New helper method.
+ (paintBorderWithTitle): New helper method.
+ (getBorderInsets): Rewritten.
+ (getMinimumSize): Rewritten.
+ (getRealJustification): Removed.
+ (getMeasurements): Removed.
+ (Measurements): Removed.
+
+2006-05-12 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/plaf/basic/BasicPanelUI.java
+ (sharedUI): New field,
+ (createUI): Return a shared instance rather than a new instance,
+ (installUI): Reformatted and added API docs,
+ (installDefaults): Install border if one is defined,
+ (uninstallDefaults): Uninstall border.
+
+2006-05-12 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JProgressBar.java: Updated API docs all over.
+
+2006-05-11 Lillian Angel <langel@redhat.com>
+
+ * java/awt/ContainerOrderFocusTraversalPolicy.java
+ (getComponentAfter): Should not throw exception if
+ the ancestor is null. Added a check for this.
+ Also, changed to use new helper function, we should
+ iterate through all the components at least once.
+ (getNextAvailableComponent): New helper function.
+ (getPrevAvailableComponent): New helper function.
+ (getComponentBefore): Should not throw exception if
+ the ancestor is null. Added a check for this.
+ Also, changed to use new helper function, we should
+ iterate through all the components at least once.
+ (getFirstComponent): Changed check to manually check
+ fields. Calling accept() casts the object to a Component,
+ so different values may be returned.
+ (getLastComponent): Likewise.
+
+2006-05-11 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/plaf/metal/MetalBorders.java: Clean up formatting/style,
+ * javax/swing/plaf/metal/MetalButtonUI.java: Likewise,
+ * javax/swing/plaf/metal/MetalCheckBoxUI.java: Likewise,
+ * javax/swing/plaf/metal/MetalComboBoxButton.java: Likewise,
+ * javax/swing/plaf/metal/MetalComboBoxIcon.java: Likewise,
+ * javax/swing/plaf/metal/MetalFileChooserUI.java: Likewise,
+ * javax/swing/plaf/metal/MetalIconFactory.java: Likewise,
+ * javax/swing/plaf/metal/MetalInternalFrameTitlePane.java: Likewise,
+ * javax/swing/plaf/metal/MetalLookAndFeel.java: Likewise,
+ * javax/swing/plaf/metal/MetalPopupMenuSeparatorUI.java: Likewise,
+ * javax/swing/plaf/metal/MetalRootPaneUI.java: Likewise,
+ * javax/swing/plaf/metal/MetalScrollBarUI.java: Likewise,
+ * javax/swing/plaf/metal/MetalSeparatorUI.java: Likewise,
+ * javax/swing/plaf/metal/MetalSliderUI.java: Likewise,
+ * javax/swing/plaf/metal/MetalSplitPaneDivider.java: Likewise,
+ * javax/swing/plaf/metal/MetalTabbedPaneUI.java: Likewise,
+ * javax/swing/plaf/metal/MetalToolTipUI.java: Likewise,
+ * javax/swing/plaf/metal/MetalUtils.java: Likewise.
+
+2006-05-11 Robert Schuster <robertschuster@fsfe.org>
+
+ * javax/swing/text/DefaultCaret.java: Made field 'textComponent'
+ package-private, added field 'active'.
+ (PropertyChangeHandler.propertyChange): Added variable 'name', added
+ cases to update field 'active'.
+ (mouseDragged): Added documentation, added if-clause to update
+ selection or caret position.
+ (mouseClicked): Added early return when text component is disabled.
+ (focusGained): Moved statements into an if-clause.
+ (focusLost): Added subexpression to if-clause.
+ (install): Preset value of 'active'.
+ (paint): Added subexpression to if-clause.
+ (isVisible): Extended return expression.
+ * javax/swing/text/JTextComponent.java:
+ (copy): Copy only if component is enabled.
+ (cut): Cut only if component is enabled and editable.
+ (paste): Dito.
+
+2006-05-11 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/plaf/multi/MultiComboBoxUI.java: Minor formatting change,
+ * javax/swing/plaf/multi/MultiFileChooserUI.java: Likewise,
+ * javax/swing/plaf/multi/MultiListUI.java: Likewise,
+ * javax/swing/plaf/multi/MultiLookAndFeel.java: Likewise,
+ * javax/swing/plaf/multi/MultiOptionPaneUI.java: Likewise,
+ * javax/swing/plaf/multi/MultiSplitPaneUI.java: Likewise,
+ * javax/swing/plaf/multi/MultiTabbedPaneUI.java: Likewise.
+
+2006-05-11 Roman Kennke <kennke@aicas.com>
+
+ * gnu/java/awt/font/GNUGlyphVector.java
+ (GNUGlyphVector): Don't apply the font renderer context's
+ transform.
+
+2006-05-11 Mark Wielaard <mark@klomp.org>
+
+ * java/util/logging/Logger.java (global): Initialize inside static
+ PrivilegedAction.
+
+2006-05-11 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JFrame.java
+ (EXIT_ON_CLOSE): Added note to API docs,
+ (close_action): Renamed closeAction,
+ (JFrame()): Change title to "",
+ (JFrame(String)): Added API docs,
+ (getAccessibleContext): Likewise,
+ (getDefaultCloseOperation): Updated for renamed field, added API docs,
+ (processWindowEvent): Updated for renamed field,
+ (setDefaultCloseOperation): Likewise, and updated API docs.
+
+2006-05-11 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JFrame.java
+ (paramString): Reimplemented,
+ * javax/swing/SwingUtilities.java
+ (convertWindowConstantToString): New method.
+
+2006-05-11 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/WindowConstants.java: Updated API docs.
+
+2006-05-11 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/plaf/basic/BasicToggleButtonUI.java: Updated API docs,
+ (createUI): Removed 'final' qualifier for parameter,
+ (paint): Reformatted.
+
+2006-05-11 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/plaf/basic/BasicCheckBoxUI.java: Added API docs plus,
+ (createUI): Removed 'final' qualifier on method argument.
+
+2006-05-11 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/plaf/basic/BasicCheckBoxUI.java
+ (getDefaultIcon): Removed this redundant method.
+
+2006-05-11 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/plaf/basic/BasicRadioButtonUI.java
+ (paint): Pass component size to paintFocus().
+
+2006-05-11 Robert Schuster <robertschuster@fsfe.org>
+
+ * java/awt/Component.java:
+ (dispatchEventImpl): Added comment.
+
+2006-05-11 Mark Wielaard <mark@klomp.org>
+
+ * tools/gnu/classpath/tools/appletviewer/Main.java (main): Cast
+ Option constructor null argument to String.
+
+2006-05-11 Mark Wielaard <mark@klomp.org>
+
+ * java/awt/geom/GeneralPath.java (WIND_EVEN_ODD, WIND_NON_ZERO):
+ Fully qualify PathIterator constants
+
+2006-05-11 Robert Schuster <robertschuster@fsfe.org>
+
+ * java/awt/Component.java:
+ (dispatchEventImpl): Added subexpression to if-clause.
+
+2006-05-11 Mark Wielaard <mark@klomp.org>
+
+ * java/util/Collections.java (UnmodifiableMapEntry): Qualify
+ Map.Entry.
+
+2006-05-10 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/TransferHandler.java: Marked stub methods.
+
+2006-05-10 Roman Kennke <kennke@aicas.com>
+
+ PR 27481
+ * javax/swing/plaf/basic/BasicInternalFrameUI.java
+ (installDefaults): Set background of content pane to null, if
+ no custom color has been installed by the application yet.
+
+2006-05-10 Sven de Marothy <sven@physto.se>
+
+ * java/awt/print/PrinterJob.java:
+ (lookupPrintServices): Un-comment-out.
+
+2006-05-10 Roman Kennke <kennke@aicas.com>
+
+ * javax/swing/JRootPane.java
+ (createContentPane): Don't set background to null.
+
+2006-05-11 Raif S. Naffah <raif@swiftdsl.com.au>
+
+ * tools/gnu/classpath/tools/getopt/OptionGroup.java
+ (FILLER): New constant.
+ (formatText(PrintStream,String,int)): New method.
+ (formatText(PrintStream,String,int,Locale)): Likewise.
+ (printHelp): Use formatText method.
+ * tools/gnu/classpath/tools/getopt/Parser.java
+ (MAX_LINE_LENGTH): New constant.
+ (formatText(PrintStream,String)): New method.
+ (formatText(PrintStream,String,Locale)): Likewise.
+ (printHelp): New method.
+ (printHelp(PrintStream)): Increased visibility to protected.
+ Use formatText method.
+
+2006-05-10 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/plaf/metal/MetalRadioButtonUI.java
+ (installDefaults): Use getPropertyPrefix() to allow subclasses to
+ modify the lookup key.
+
+2006-05-10 Lillian Angel <langel@redhat.com>
+
+ * java/util/SimpleTimeZone.java: Reverted patch.
+ (SimpleTimeZone): Throw exception if startMonth ==
+ endMonth.
+ (SimpleTimeZone): Likewise.
+ (checkRule): Rewritten to properly check all values (more
+ efficently).
+ This code is now more stable, at least less buggy than before.
+ Fixed API documentation.
+ (setStartRule): Moved checkRule call to end.
+ (setStartRule): Likewise.
+ (setEndRule): Likewise.
+ (setEndRule): Likewise.
+
+2006-05-10 Roman Kennke <kennke@aicas.com>
+
+ * gnu/java/awt/peer/swing/SwingComponent.java:
+ Some API comment fixlets.
+ * gnu/java/awt/peer/swing/SwingComponentPeer.java:
+ (createImage): Create a BufferedImage, not a Toolkit image.
+ (paint): Removed bogus API comment.
+ (prepareImage): Added checks to avoid NPE.
+ * gnu/java/awt/peer/swing/SwingContainerPeer.java:
+ (getInsets): Added check to avoid NPE.
+ (handleMouseEvent): Added check to avoid NPE.
+ * gnu/java/awt/peer/swing/SwingFramePeer.java:
+ Some API comment fixlets.
+ * gnu/java/awt/peer/swing/SwingMenuBarPeer.java:
+ Some API comment fixlets.
+ * gnu/java/awt/peer/swing/SwingTextFieldPeer.java:
+ Changed start_pos name to startPos.
+ * gnu/java/awt/peer/swing/SwingWindowPeer.java:
+ Some API comment fixlets.
+
+2006-05-10 David Gilbert <david.gilbert@object-refinery.com>
+
+ * java/awt/BasicStroke.java
+ (equals): Fixed typo in HTML tag for API doc comment.
+
+2006-05-10 Gary Benson <gbenson@redhat.com>
+
+ * java/lang/ThreadGroup.java (parent): Make package-private.
+ * java/lang/SecurityManager.java (checkAccess(Thread)):
+ Reference ThreadGroup.parent directly to avoid extra checks.
+ * java/lang/SecurityManager.java (checkAccess(ThreadGroup)):
+ Likewise.
+
+2006-05-10 Roman Kennke <kennke@aicas.com>
+
+ Reported by Ingo Proetel (proetel@aicas.com)
+ * java/awt/EventDispatchThread.java
+ (DEFAULT_PRIORITY): New constant field.
+ (EventDispatchThread()): Added gnu.awt.dispatchthread.priority
+ system property for adjusting the priority of the event
+ dispatch thread.
+
+2006-05-10 Roman Kennke <kennke@aicas.com>
+
+ Reported by Ingo Proetel (proetel@aicas.com)
+ * java/awt/image/ColorModel.java
+ (S_RGB_MODEL): New constant field.
+ (getRGBDefault): Return constant SRGBColorModel.
+ (SRGBColorModel): Specialized color model for sRGB.
+
+2006-05-10 Roman Kennke <kennke@aicas.com>
+
+ * java/awt/ColorPaintContext.java
+ (getRaster): Create Raster with (0,0) as source location.
+
+2006-05-10 Roman Kennke <kennke@aicas.com>
+
+ * gnu/java/awt/java2d/AlphaCompositeContext.java
+ (compose): Don't premultiply alpha to alpha itself.
+
+2006-05-10 Roman Kennke <kennke@aicas.com>
+
+ * gnu/java/awt/java2d/AbstractGraphics2D.java
+ (drawImage(Image,AffineTransform,ImageObserver)): Implemented.
+ (drawImageImpl(Image,AffineTransform,ImageObserver,Rectangle)):
+ New method.
+ (drawImage(BufferedImage,BufferedImageOp,int,int)): Implemented.
+ (drawRenderedImage(RenderedImage,AffineTransform)): Implemented.
+ (drawRenderedImageImpl(RenderedImage,AffineTransform,Rectangle)):
+ New method.
+ (drawRenderableImage(RenderableImage,AffineTransform)): Implemented.
+ (drawRenderableImageImpl(RenderableImage,AffineTransform,Rectangle)):
+ New method.
+ (scale): Inverse transform by doing 1/scale instead of -scale.
+ (drawImage(Image,int,int,ImageObserver)): Implemented.
+ (drawImage(Image,int,int,int,int,ImageObserver)): Implemented.
+ (drawImage(Image,int,int,Color,ImageObserver)): Implemented.
+ (drawImage(Image,int,int,int,int,Color,ImageObserver)): Implemented.
+ (drawImage(Image,int,int,int,int,int,int,int,int,ImageObserver)):
+ Implemented.
+ (drawImage(Image,int,int,int,int,int,int,int,int,Color,ImageObserver)):
+ Implemented.
+ (fillScanline): Work on translated destination raster for
+ correct compositin.
+ (init): Fetch the clip after the destination raster is initialized.
+ * gnu/java/awt/java2d/ImagePaint.java: New file.
+ * gnu/java/awt/java2d/RasterGraphics
+ (drawImage): Removed.
+
+2006-05-09 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * resource/gnu/classpath/tools/appletviewer/MessagesBundle.properties:
+ Clarify option descriptions.
+ * tools/gnu/classpath/tools/appletviewer/Main.java: Use all
+ uppercase for metasyntactic variables.
+
+2006-05-09 Robert Schuster <robertschuster@fsfe.org>
+
+ Fixed PR24216.
+ * javax/swing/text/AbstractDocument.java:
+ (insertString): Added more documentation, added argument check.
+ (remove): Added more documentation.
+ (removeImpl): Added argument check.
+ (replace): Added more documentation, added argument check.
+
+2006-05-09 Tom Tromey <tromey@redhat.com>
+
+ * tools/.cvsignore: Added appletviewer.
+
+2006-05-09 Tom Tromey <tromey@redhat.com>
+
+ * tools/gnu/classpath/tools/getopt/Parser.java (printHelp): Skip
+ empty groups.
+
+2006-05-09 Tom Tromey <tromey@redhat.com>
+
+ * tools/gnu/classpath/tools/getopt/OptionGroup.java (printHelp):
+ Special case for '-J'. Use space instead of '='.
+ * tools/gnu/classpath/tools/getopt/Parser.java (setHeader): Added
+ comment.
+
+2006-05-09 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * configure.ac: Add --disable-plugin and --with-vm options. Check
+ for plugin support headers and libraries.
+ * native/Makefile.am: Recurse into plugin directory.
+ * native/plugin/.cvsignore: New file.
+ * native/plugin/Makefile.am: New file.
+ * native/plugin/gcjwebplugin.cc: New file.
+ * tools/Makefile.am: Install appletviewer wrapper script.
+ * tools/appletviewer.in: Replace VM location heuristic with
+ VM_BINARY configure substitution.
+
+2006-05-09 Tom Tromey <tromey@redhat.com>
+
+ * tools/gnu/classpath/tools/getopt/OptionGroup.java (printHelp): Added
+ an initial pass to look for short options. Added 'longOnly' option.
+ * tools/gnu/classpath/tools/appletviewer/Main.java (main): Removed -J
+ option.
+ * tools/gnu/classpath/tools/getopt/Parser.java (parsed): Put stadnard
+ options into final group. Added -J.
+ (add): Insert new groups before final group.
+ (printHelp): Updated.
+
+2006-05-09 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ PR 27518
+ * tools/gnu/classpath/tools/giop/GRMIC.java (main),
+ tools/gnu/classpath/tools/rmi/RMIC.java (main):
+ Expect -classpath option.
+ * tools/gnu/classpath/tools/rmi/RMIC.txt,
+ tools/gnu/classpath/tools/giop/GRMIC.txt: Documenting
+ -classpath option.
+ tools/gnu/classpath/tools/giop/grmic/GiopRmicCompiler.java
+ (classLoader): New field. (loadClass, setClassPath):
+ New methods.
+
+2006-05-09 Roman Kennke <kennke@aicas.com>
+
+ * gnu/java/awt/java2d/RasterGraphics.java
+ (RasterGraphics): Call init() and super().
+ (drawImage): Temporary drawImage impl until AbstractGraphics2D has
+ this.
+
+2006-05-09 Gary Benson <gbenson@redhat.com>
+
+ * java/lang/Thread.java (Thread): Always perform threadgroup
+ access checks on thread creation.
+
+2006-05-09 Chris Burdess <dog@gnu.org>
+
+ * gnu/xml/dom/DomNode.java: Permit comments and PIs in doctype nodes to
+ be preserved during cloneNode.
+
+2006-05-09 Audrius Meskauskas <AudriusA@Bioinformatics.org>
+
+ PR 27517
+ * tools/gnu/classpath/tools/giop/grmic/GiopRmicCompiler.java (compile):
+ Do not demand all thrown exceptions to be an instance of RemoteException.
+
+2006-05-09 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * resource/gnu/classpath/tools/appletviewer/MessagesBundle.properties:
+ Use hash-style comments.
+ * resource/gnu/classpath/tools/appletviewer/MessagesBundle_de.properties:
+ Likewise.
+
+2006-05-09 David Gilbert <david.gilbert@object-refinery.com>
+
+ * javax/swing/JLabel.java
+ (paramString): Added more attribute details,
+ * javax/swing/SwingUtilities.java
+ (convertHorizontalAlignmentCodeToString): New method,
+ (convertVerticalAlignmentCodeToString): New method.
+
+2006-05-08 Tom Tromey <tromey@redhat.com>
+
+ * tools/gnu/classpath/tools/jar/Updater.java (run): Updated.
+ * tools/gnu/classpath/tools/jar/Main.java: Use javadoc for fields.
+ * tools/gnu/classpath/tools/jar/Lister.java (listJar): Use
+ ZipInputStream.
+ (run): Updated.
+ * tools/gnu/classpath/tools/jar/Extractor.java (run): Use System.err
+ for verbose.
+ (run): Use ZipInputStream.
+ (initSet): New method.
+ (shouldExtract): Likewise.
+ (run): Use new methods.
+ * tools/gnu/classpath/tools/jar/Creator.java
+ (writeCommandLineEntries): New overload.
+ (writeFile): Use System.err for verbose.
+ (writeManifest): New method.
+ (writtenItems): New field.
+ (writeFile): Update it.
+ (writeCommandLineEntries): Return void. Call writeManifest.
+ (addEntries): Don't add extra '/'.
+ * NEWS: Mention jar.
+
2006-05-08 Lillian Angel <langel@redhat.com>
* gnu/java/net/IndexListParser.java: New class.
@@ -1699,7 +5094,7 @@
2006-04-21 David Gilbert <david.gilbert@object-refinery.com>
* javax/swing/border/AbstractBorder.java: API doc updates,
- * javax/swing/border/BevelBorder.java: Likewise,
+ * javax/swing/border/BevelBorder.java: Likewise,
* javax/swing/border/CompoundBorder.java: Likewise,
* javax/swing/border/EtchedBorder.java: Likewise,
* javax/swing/border/LineBorder.java: Likewise,
@@ -2057,7 +5452,8 @@
2006-04-18 Robert Schuster <robertschuster@fsfe.org>
- * javax/swing/plaf/basic/BasicTextUI.java: Implemented.
+ * javax/swing/plaf/basic/BasicTextUI.java:
+ (getNextVisualPositionFrom): Implemented.
2006-04-18 David Gilbert <david.gilbert@object-refinery.com>
@@ -5839,21 +9235,6 @@
* vm/reference/gnu/classpath/Unsafe.java:
New class to handle low-level facilities for concurrency.
-2006-03-19 Michael Barker <mike@middlesoft.co.uk>
-
- * vm/reference/gnu/java/nio/VMChannel.java: Added, supports setting
- non-blocking and scatter-gather io operations.
- * gnu/java/nio/PipeImpl.java: Retrofitted to use VMChannel
- * gnu/java/nio/SelectorImpl.java
- (register) Added condition for gnu.java.nio.SocketChannelSelectionKeyImpl
- * gnu/java/nio/SocketChannelSelectionKeyImpl.java Added.
- * gnu/java/nio/channels/FileChannelImpl.java: Retrofitted to use VMChannel
- * java/nio/FileChannel.java
- (read (ByteBuffer)) Changed to call abstract method.
- (write (ByteBuffer)) Changed to call abstract method.
- * include/gnu_java_nio_VMChannel.h: Added.
- * native/jni/java-nio/gnu_java_nio_VMChannel.c: Added.
-
2006-03-19 Mark Wielaard <mark@klomp.org>
* include/Makefile.am: Rename PlainDatagramSocketImpl to
@@ -12205,7 +15586,7 @@
(AccessibleJComponent.changeSupport): Changed to be a
java.beans.PropertyChangeSupport rather than
SwingPropertyChangeSupport.
- (AccessibleJComponent.AccesibleJComponent()): Change initialization
+ (AccessibleJComponent.AccessibleJComponent()): Change initialization
of above field.
(changeSupport): Removed unneeded field.
(removePropertyChangeListener): Removed unneeded methods.
diff --git a/ChangeLog.native b/ChangeLog.native
index 28a1db5c8..92940903b 100644
--- a/ChangeLog.native
+++ b/ChangeLog.native
@@ -1,3 +1,10 @@
+2006-06-07 Guilhem Lavaux <guilhem@kaffe.org>
+
+ * Merged HEAD as of 2006-06-06.
+
+ * native/jni/native-lib/cpproc.h
+ (CPIO_EXEC_NUM_PIPES): Compilation fix.
+
2006-06-06 Guilhem Lavaux <guilhem@kaffe.org>
* Merged HEAD as of 2006-05-08.
diff --git a/INSTALL b/INSTALL
index 96059a50a..97983fdce 100644
--- a/INSTALL
+++ b/INSTALL
@@ -46,13 +46,13 @@ Suggested Software
are required unless --disable-gtk-peer is used as an argument to
configure.
- - GTK+ 2.4.x (or higher)
+ - GTK+ 2.8.x (or higher)
- gdk-pixbuf
- XTest Extension (libXtst) for GdkRobot support in java.awt.
- For building the Cairo GdkGraphics2D backend you need at least
- Cairo 0.5.0.
+ For building gcjwebplugin you'll need the Mozilla plugin
+ support headers and libraries.
For building the Qt AWT peer JNI native libraries you have to
specify --enable-qt-peer and need the following library:
@@ -113,7 +113,6 @@ gives a complete list.
--enable-java compile Java source default=yes
--enable-jni compile JNI source default=yes
--enable-gtk-peer compile GTK native peers default=yes
- --enable-gtk-cairo compile cairo based Graphics2D default=no
--enable-qt-peer compile Qt4 native peers default=no
--enable-default-toolkit
fully qualified class name of default AWT toolkit
diff --git a/NEWS b/NEWS
index 2cd7afa5b..8a67dedd7 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,34 @@
-New in release 0.92
+New in release 0.92 (UNRELEASED)
+
+* libjawtgnu.so has been renamed libjawt.so for binary compatibility.
+ libjawt.so should be installed in a VM-specific directory rather
+ than directly in /usr/lib. Proprietary VMs put their libjawt.so
+ implementations in VM-specific directories but search /usr/lib first.
+ If GNU Classpath's libjawt.so is installed in /usr/lib it will create
+ problems for people who use a proprietary VM to run AWT Native
+ Interface applications.
+* The GdkGraphics2D backend has been made the default. There is no
+ longer an explicit dependency on Cairo, the --enable-gtk-cairo
+ configure option is gone, and GTK 2.8 or higher is now required to
+ build the GTK peers.
+* A Mozilla plugin, 'gcjwebplugin', is now included. It introduces a
+ dependency on the Mozilla plugin support headers and libraries.
+* Several new tools are now included:
+ * appletviewer
+ * jar
+ * native2ascii
+ * serialver
+ A new configure option --enable-tool-wrappers causes wrapper
+ binaries to be built for VMs that support the JNI Invocation API.
-New in release 0.91 (UNRELEASED)
+Runtime interface changes:
+
+* A new class, VMURLConnection, is used to implement
+ URLConnection.guessContentTypeFromStream. The reference
+ implementation uses libmagic (and falls back to doing nothing if
+ libmagic is not available).
+
+New in release 0.91 (May 15, 2006)
* Experimental activation (java.rmi.activation) support, including RMI
activation daemon and persistent naming service tools.
@@ -60,6 +88,9 @@ Runtime interface changes:
* java.lang.Package now has a new constructor that takes the defining
ClassLoader as an extra argument. If you use a custom version of
VMClassLoader, please switch it to use this constructor.
+* The reference implementation of VMClassLoader.getBootPackages() now
+ reads the META-INF/INDEX.LIST resource using the java.boot.class.path
+ system property.
New in release 0.90 (March 6, 2006)
diff --git a/README b/README
index 27e22dcce..132fbe531 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-GNU Classpath README - Last updated: August 31, 2005
+GNU Classpath README - Last updated: May 15, 2006
GNU Classpath, Essential Libraries for Java is a project to create a
free software implementation of the core class libraries for the java
@@ -29,6 +29,7 @@ Smaller environments (runtime only, no compilers, no tools) which work
with this GNU Classpath releases include
(tested by and recommended for GNU Classpath hackers):
+ * CACAO (http://www.cacaojvm.org/)
* JamVM (http://jamvm.sourceforge.net/)
* Jikes RVM (http://www.ibm.com/developerworks/oss/jikesrvm/)
* Kissme (http://kissme.sourceforge.net/)
diff --git a/THANKYOU b/THANKYOU
index d191d7c05..cb93e25b1 100644
--- a/THANKYOU
+++ b/THANKYOU
@@ -27,6 +27,7 @@ Steven Hugg (hugg@pobox.com)
jockey@aromasoft.com
Isaac Jones (ijones@cis.ohio-state.edu)
Oskar Liljeblad (osk@hem.passagen.se)
+Trevor Linton (tlinton@xmission.com)
Casey Marshall (rsdio@metastatic.org)
Steve Mayer (SMayer@dynamicsoft.com)
Matt Mucklo (mmucklo@jumpsmart.com)
diff --git a/configure.ac b/configure.ac
index cb95ef2f0..5495c4022 100644
--- a/configure.ac
+++ b/configure.ac
@@ -165,23 +165,6 @@ dnl GTK native peer error checking
dnl -----------------------------------------------------------
AC_ARG_ENABLE([gtk-peers],,AC_MSG_ERROR([No --enable-gtk-peers (or --disable-gtk-peers) option; you want --enable-gtk-peer]))
-dnl ------------------------------------------------------------
-dnl determine whether to enable the cairo GTK Graphics2D backend
-dnl ------------------------------------------------------------
-AC_ARG_ENABLE([gtk-cairo],
- [AS_HELP_STRING(--enable-gtk-cairo,build the cairo Graphics2D implementation on GTK [default=no])],
- [case "${enableval}" in
- yes) GTK_CAIRO_ENABLED=true ;;
- no) GTK_CAIRO_ENABLED=false ;;
- *) GTK_CAIRO_ENABLED=true ;;
- esac],
- [GTK_CAIRO_ENABLED=false])
-AC_SUBST(GTK_CAIRO_ENABLED)
-if test "x${GTK_CAIRO_ENABLED}" = xtrue; then
- AC_DEFINE(GTK_CAIRO, 1, [defined if cairo support was built in])
-fi
-AM_CONDITIONAL(GTK_CAIRO, test "x${GTK_CAIRO_ENABLED}" = xtrue)
-
dnl -----------------------------------------------------------
dnl Qt native peer (disabled by default)
dnl -----------------------------------------------------------
@@ -195,12 +178,24 @@ AC_ARG_ENABLE([qt-peer],
[COMPILE_QT_PEER=no])
AM_CONDITIONAL(CREATE_QT_PEER_LIBRARIES, test "x${COMPILE_QT_PEER}" = xyes)
+dnl -----------------------------------------------------------
+dnl Plugin (enabled by default)
+dnl -----------------------------------------------------------
+AC_ARG_ENABLE([plugin],
+ [AS_HELP_STRING(--disable-plugin,compile gcjwebplugin (disabled by --disable-plugin) [default=yes])],
+ [case "${enableval}" in
+ yes) COMPILE_PLUGIN=yes ;;
+ no) COMPILE_PLUGIN=no ;;
+ *) COMPILE_PLUGIN=yes ;;
+ esac],
+ [COMPILE_PLUGIN=yes])
+AM_CONDITIONAL(CREATE_PLUGIN, test "x${COMPILE_PLUGIN}" = xyes)
dnl -----------------------------------------------------------
dnl Sets the native libraries installation dir
dnl -----------------------------------------------------------
AC_ARG_WITH([native-libdir],
- [AS_HELP_STRING(--with-native-libdir,sets the installation directore for native libraries [default='${libdir}/${PACKAGE}'])],
+ [AS_HELP_STRING(--with-native-libdir,sets the installation directory for native libraries [default='${libdir}/${PACKAGE}'])],
[
nativeexeclibdir=${withval}
],
@@ -225,6 +220,21 @@ AC_ARG_WITH([glibj-dir],
AC_SUBST(glibjdir)
dnl -----------------------------------------------------------
+dnl Sets the VM name for use in tool wrapper scripts
+dnl -----------------------------------------------------------
+AC_ARG_WITH([vm],
+ [AS_HELP_STRING(--with-vm,sets the VM binary name [default='${prefix}/bin/jamvm'])],
+ [
+ VM_BINARY=${withval}
+ ],
+ [
+ VM_BINARY='${prefix}/bin/jamvm'
+ ])
+
+AC_SUBST(VM_BINARY)
+AM_CONDITIONAL(FOUND_CACAO, test "x`basename $VM_BINARY`" = xcacao)
+
+dnl -----------------------------------------------------------
dnl Regenerate headers at build time (disabled by default)
dnl -----------------------------------------------------------
AC_ARG_ENABLE([regen-headers],
@@ -237,6 +247,20 @@ AC_ARG_ENABLE([regen-headers],
[REGENERATE_JNI_HEADERS=no])
AM_CONDITIONAL(CREATE_JNI_HEADERS, test "x${REGENERATE_JNI_HEADERS}" = xyes)
+dnl -----------------------------------------------------------
+dnl Enable tool wrapper binaries (disabled by default)
+dnl -----------------------------------------------------------
+AC_ARG_ENABLE([tool-wrappers],
+ [AS_HELP_STRING(--enable-tool-wrappers,create tool wrapper binaries [default=no])],
+ [case x"${enableval}" in
+ xyes) COMPILE_WRAPPERS=yes ;;
+ xno) COMPILE_WRAPPERS=no ;;
+ x) COMPILE_WRAPPERS=yes ;;
+ *) COMPILE_WRAPPERS=yes ;;
+ esac],
+ [COMPILE_WRAPPERS=no])
+AM_CONDITIONAL(CREATE_WRAPPERS, test "x${COMPILE_WRAPPERS}" = xyes)
+
AC_PROG_LN_S
AC_PROG_INSTALL
@@ -282,7 +306,8 @@ if test "x${COMPILE_JNI}" = xyes; then
sys/select.h \
crt_externs.h \
fcntl.h \
- sys/mman.h])
+ sys/mman.h \
+ magic.h])
AC_EGREP_HEADER(uint32_t, stdint.h, AC_DEFINE(HAVE_INT32_DEFINED, 1, [Define to 1 if you have uint32_t]))
AC_EGREP_HEADER(uint32_t, inttypes.h, AC_DEFINE(HAVE_INT32_DEFINED, 1, [Define to 1 if you have uint32_t]))
@@ -300,6 +325,10 @@ if test "x${COMPILE_JNI}" = xyes; then
mmap munmap mincore msync madvise getpagesize sysconf \
])
+ LIBMAGIC=
+ AC_CHECK_LIB(magic, magic_open, LIBMAGIC=-lmagic)
+ AC_SUBST(LIBMAGIC)
+
AC_HEADER_TIME
AC_STRUCT_TM
AC_STRUCT_TIMEZONE
@@ -373,26 +402,28 @@ if test "x${COMPILE_JNI}" = xyes; then
AC_MSG_ERROR([GTK+ peers requested but no X library available])
fi
dnl We explicitly want the XTest Extension for Robot support.
- AC_CHECK_LIB([Xtst], [XTestQueryExtension], [true],
- [AC_MSG_ERROR([libXtst NOT found, required for GdkRobot])],
- [${X_LIBS}])
- PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.4 gthread-2.0 >= 2.2 gdk-pixbuf-2.0)
-
- if test "x${enable_gtk_cairo}" = xyes; then
- PKG_CHECK_MODULES(CAIRO, cairo >= 0.5.0)
- fi
+ AC_CHECK_LIB([Xtst], [XTestQueryExtension],
+ [XTEST_LIBS="$XTEST_LIBS -lX11 -lXtst"],
+ [AC_MSG_ERROR([libXtst NOT found, required for GdkRobot])],
+ [${X_LIBS}])
+ PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.8 gthread-2.0 >= 2.2 gdk-pixbuf-2.0)
PKG_CHECK_MODULES(FREETYPE2, freetype2)
PKG_CHECK_MODULES(PANGOFT2, pangoft2)
+ dnl Check if we can link against the XRender library and set
+ dnl HAVE_XRENDER accordingly.
+ AC_CHECK_LIB([Xrender], [XRenderQueryExtension],
+ [AC_DEFINE(HAVE_XRENDER, 1, [Define to 1 if you have libXrender.])[X_EXTRA_LIBS="$X_EXTRA_LIBS -lXrender"]],
+ [true],
+ [${X_LIBS}])
AC_SUBST(GTK_CFLAGS)
AC_SUBST(GTK_LIBS)
- AC_SUBST(CAIRO_LIBS)
- AC_SUBST(CAIRO_CFLAGS)
AC_SUBST(FREETYPE2_LIBS)
AC_SUBST(FREETYPE2_CFLAGS)
AC_SUBST(PANGOFT2_LIBS)
AC_SUBST(PANGOFT2_CFLAGS)
+ AC_SUBST(XTEST_LIBS)
fi
dnl Check for AWT related Qt4
@@ -443,6 +474,25 @@ if test "x${COMPILE_JNI}" = xyes; then
AC_SUBST(QT_CFLAGS)
AC_SUBST(QT_LIBS)
fi
+
+ dnl Check for plugin support headers and libraries.
+ if test "x${COMPILE_PLUGIN}" = xyes; then
+ PKG_CHECK_MODULES(MOZILLA, mozilla-plugin, [MOZILLA_FOUND=yes], [MOZILLA_FOUND=no])
+ if test "x${MOZILLA_FOUND}" = xno; then
+ PKG_CHECK_MODULES(MOZILLA, firefox-plugin, [MOZILLA_FOUND=yes], [MOZILLA_FOUND=no])
+ fi
+ if test "x${MOZILLA_FOUND}" = xno; then
+ PKG_CHECK_MODULES(MOZILLA, xulrunner-plugin, [MOZILLA_FOUND=yes], [MOZILLA_FOUND=no])
+ fi
+ PKG_CHECK_MODULES(GLIB, glib-2.0)
+
+ AC_SUBST(MOZILLA_CFLAGS)
+ AC_SUBST(MOZILLA_LIBS)
+ AC_SUBST(GLIB_CFLAGS)
+ AC_SUBST(GLIB_LIBS)
+
+ AC_SUBST(PLUGIN_DIR, $HOME/.mozilla/plugins/)
+ fi
fi
CLASSPATH_WITH_JAVAH
@@ -668,21 +718,27 @@ native/jni/xmlj/Makefile
native/jni/midi-alsa/Makefile
native/jni/midi-dssi/Makefile
native/jni/native-lib/Makefile
+native/plugin/Makefile
resource/Makefile
scripts/Makefile
scripts/classpath.spec
lib/Makefile
lib/gen-classlist.sh
lib/copy-vmresources.sh
-tools/appletviewer
tools/Makefile
-tools/jarsigner
-tools/keytool
examples/Makefile
examples/Makefile.jawt])
-AC_CONFIG_COMMANDS([gen-classlist],[chmod 755 lib/gen-classlist.sh])
-AC_CONFIG_COMMANDS([copy-vmresources],[chmod 755 lib/copy-vmresources.sh])
+
+if test "x${COMPILE_WRAPPERS}" = xno
+then
+AC_CONFIG_FILES([tools/appletviewer
+tools/jarsigner
+tools/keytool])
AC_CONFIG_COMMANDS([appletviewer],[chmod 755 tools/appletviewer])
AC_CONFIG_COMMANDS([jarsigner],[chmod 755 tools/jarsigner])
AC_CONFIG_COMMANDS([keytool],[chmod 755 tools/keytool])
+fi
+
+AC_CONFIG_COMMANDS([gen-classlist],[chmod 755 lib/gen-classlist.sh])
+AC_CONFIG_COMMANDS([copy-vmresources],[chmod 755 lib/copy-vmresources.sh])
AC_OUTPUT
diff --git a/doc/www.gnu.org/announce/20060515.wml b/doc/www.gnu.org/announce/20060515.wml
new file mode 100644
index 000000000..deb127f86
--- /dev/null
+++ b/doc/www.gnu.org/announce/20060515.wml
@@ -0,0 +1,217 @@
+#!wml --include=..
+
+#use wml::std::page
+#use wml::std::lang
+#use wml::fmt::isolatin
+#use wml::std::case global=upper
+
+<lang:star:slice:>
+
+<set-var last-modified-author="mjw">
+
+#include <include/macros.wml>
+
+<header title="GNU Classpath 0.91 Announcement (2006-05-15)">
+<pre>
+GNU Classpath 0.91 "All for One, One for All" released
+
+GNU Classpath, essential libraries for java, is a project to create
+free core class libraries for use with runtimes, compilers and tools
+for the java programming language.
+
+The GNU Classpath developer snapshot releases are not directly aimed
+at the end user but are meant to be integrated into larger development
+platforms. For example the GCC (gcj) and Kaffe projects will use the
+developer snapshots as a base for future versions. More projects based
+on GNU Classpath: http://www.gnu.org/software/classpath/stories.html
+
+Some highlights of changes in this release (more extensive list below):
+
+ RMI activation daemon and persistent naming service tools are now
+ included. Print service discovery, single document print jobs and
+ support for client-formatted print data through CUPS has been
+ added. Support for custom mouse cursors, system clipboard and
+ selection access has been implemented. A Free Swing OceanTheme and
+ support for assistive technologies (accessibility) has been
+ added. The VM runtime interface has been merged with the generics
+ version to support annotations and other 1.5 language features.
+
+GNU Classpath 0.91 does not yet support all new 1.5 additions, but
+there is also an experimental GNU Classpath "generics" release.
+classpath-0.91-generics contains a version of the core library that
+uses the new 1.5 language features such as generics and
+enumerations. ECJ, JamVM, IKVM and Cacao are known to support the
+generics release. And you can use it to run Eclipse 3.1 with it to
+develop programs that use the new 1.5 language and core library
+additions. classpath-generics is a work in progress and not as
+extensively tested as our regular releases. But please try it out if
+you want to help us test the new 1.5 support of the core libraries.
+
+The GNU Classpath developers site http://developer.classpath.org/
+provides detailed information on how to start with helping the GNU
+Classpath project and gives an overview of the core class library
+packages currently provided. For each snapshot release generated
+documentation is provided through the GNU Classpath Tools gjdoc
+project. A documentation generation framework for java source
+files used by the GNU project. Full documentation on the currently
+implementated packages and classes can be found at:
+http://developer.classpath.org/doc/
+
+For more information about the project see also:
+
+- GNU Classpath home page:
+ http://www.gnu.org/software/classpath/
+
+- Developer information (wiki):
+ http://developer.classpath.org/
+
+- Full class documentation
+ http://developer.classpath.org/doc/
+
+- GNU Classpath hackers:
+ http://planet.classpath.org/
+
+- Autobuilder, current build status, build snapshots:
+ http://builder.classpath.org/
+
+- Application test pages (wiki)
+ http://developer.classpath.org/mediation/FreeAWTTestApps
+ http://developer.classpath.org/mediation/FreeSwingTestApps
+ http://developer.classpath.org/mediation/FreeSWTTestApps
+
+- GNU Classpath hacking with Eclipse (wiki)
+ http://developer.classpath.org/mediation/ClasspathHackingWithEclipse
+
+- GNU Classpath promotion banners:
+ http://developer.classpath.org/mediation/ClasspathBanners
+
+This release depends on gtk+ 2.4 for AWT support. But gtk+ 2.6 or
+higher is recommended. Included, but not activated by default in this
+release is a Graphics2D implementation based on the Cairo Graphics
+framework (http://www.cairographics.org). Enabling this makes programs
+like JFreeChart and JEdit start up on GNU Classpath based runtimes.
+To enable this support install the cairo 0.5.x snapshot, configure GNU
+Classpath with --enable-gtk-cairo.
+
+One of the major focuses of the GNU Classpath project is expanding and
+using the Mauve test suite for Compatibility, Completeness and
+Correctness checking. Various groups around GNU Classpath collaborate
+on the free software Mauve test suite which contains more than 45.000
+core library tests. Mauve has various modules for testing core class
+library implementations, byte code verifiers, source to byte code and
+native code compiler tests. Mauve also contains the Wonka visual test
+suite and the Jacks Compiler Killer Suite.
+See for more information: http://www.sourceware.org/mauve/
+This release passes 44975 out of 45537 Mauve core library tests.
+
+Conformance reports for the included jaxp support can be found in the
+doc/README.jaxp file.
+
+GNU Classpath 0.91 can be downloaded from
+ftp://ftp.gnu.org/pub/gnu/classpath/
+or one of the ftp.gnu.org mirrors
+http://www.gnu.org/order/ftp.html
+
+File: classpath-0.91.tar.gz
+MD5sum: 3ce11b4b990b108c5ab93894fcc61be6
+SHA1sum: fcbfdf64f7a990f1747621772a2e9e69d0baaab7
+
+File: classpath-0.91-generics.tar.gz (EXPERIMENTAL)
+MD5sum: e79132b1b8441523b8f4f6a8f2d2910b
+SHA1sum: 90be3b2115e8a0288bcb6e2d1860fe58b42c77b5
+
+New in release 0.91 (May 14, 2006)
+(See the ChangeLog file for a full list of changes.)
+
+* Experimental activation (java.rmi.activation) support, including RMI
+ activation daemon and persistent naming service tools.
+* Experimental printing support: The API implementation of the javax.print
+ packages has been finished and work on the printing provider implementation
+ started. Currently supported features from the Java Print Service API are
+ print service discovery (CUPS registered printers), single document print
+ jobs and support for client-formatted print data. An example application
+ (see: examples/gnu/classpath/examples/print/Demo) has been added to show
+ the API usage for service discovery and printing of files.
+* The GTKToolkit now gives access to the both the system clipboard and
+ system selection.
+* Custom mouse cursor support has been added to the gtk+ peers. And cursors
+ can now also be set on light-weight components.
+* Free Swing improvements: Support for OceanTheme has been mostly completed
+ and turned on as default Metal theme. X11-style Copy and Paste behavior in
+ text components with the middle mouse button. Support cursor changes on
+ various components when resizing. Support for Look and Feel window
+ decorations has been added.
+* Updated locale data information to CLDR 1.3.
+* Various bugs in Classpath's SecureRandom implementations have been
+ fixed; that class now respects the "securerandom.source" security
+ property and the "java.security.egd" system property.
+* Support for assistive technologies has been added to AWT and Swing.
+
+Runtime interface changes:
+
+* A new class, VMArray, is now available which separates the native
+ array creation method from java.lang.reflect.Array.
+* A new class, gnu.classpath.Unsafe, is provided for handling the
+ new low-level operations required by java.util.concurrent.
+* The reference implementations of Method, Constructor, and Field
+ now have a new native getModifiersInternal() method. The public
+ getModifiers() method in each case has been rewritten in terms of
+ this method.
+* The reference implementation of VMThread has been updated to handle
+ the new Thread.UncaughtExceptionHandler support.
+* A new class, java.security.VMSecureRandom, is now available that is
+ used to generate random numbers for seeding cryptographically-secure
+ pseudo-random number generators.
+* VMClass and the reference implementations of Method, Constructor and Field
+ now include a number of 1.5 methods imported from the generics branch.
+ These are all optional (in the sense that the methods associated with them
+ merely fail on use if the VM doesn't provide them, rather than the
+ VM failing altogether), but VMs should aim to support them where possible.
+* The implementation of java.lang.instrument has been merged to the main
+ branch from the generics branch.
+* The VM interfaces of the main branch and the generics branch are now
+ consistent with one another. As a result, the main branch includes an
+ additional environ() function in VMSystem and an additional argument has
+ been added to nativeSpawn() in VMProcess.
+* Annotation support is now available in the main branch, if the VM supports
+ it. The VM should implement VMClass.getDeclaredAnnotations,
+ Constructor.getAnnotation, Constructor.getDeclaredAnnotations,
+ Field.getAnnotation, Field.getDeclaredAnnotations, Method.getAnnotation and
+ Method.getDeclaredAnnotations.
+* java.lang.Package now has a new constructor that takes the defining
+ ClassLoader as an extra argument. If you use a custom version of
+ VMClassLoader, please switch it to use this constructor.
+* The reference implementation of VMClassLoader.getBootPackages() now
+ reads the META-INF/INDEX.LIST resource using the java.boot.class.path
+ system property.
+
+New/Untested/Disabled Features:
+
+ The following new features are included, but not ready for
+ production yet. They are explicitly disabled and not supported. But
+ if you want to help with the development of these new features we
+ are interested in feedback. You will have to explicitly enable them
+ to try them out (and they will most likely contain bugs). If you are
+ interested in any of these then please join the mailing-list and
+ follow development in CVS.
+
+* Cairo Gtk+ Graphics2D support, enabled by giving configure
+ --enable-gtk-cairo.
+* QT4 AWT peers, enable by giving configure --enable-qt-peer.
+
+The following people helped with this release:
+
+Andrew John Hughes, Anthony Balkissoon, Arnaud Vandyck, Audrius
+Meskauskas, Bernhard Rosenkraenzer, Bryce McKinlay, Caolan McNamara,
+Carsten Neumann, Casey Marshall, Chris Burdess, Christian Thalinger,
+Dalibor Topic, David Gilbert, Fridjof Siebert, Gary Benson, Ito
+Kazumitsu, Jeroen Frijters, John K Peterson, John Sullivan, Keith
+Seitz, Lillian Angel, Mark Wielaard, Michael Barker, Michael Koch,
+Nicolas Geoffray, Olivier Jolly, Paul Jenner, Rafael H. Schloming,
+Raif S. Naffah, Riccardo Mottola, Robert Schuster, Roman Kennke,
+Sascha Brawer, Stephen White, Sven de Marothy, Thomas Fitzsimmons,
+Tom Tromey and Wolfgang Baer.
+
+We would also like to thank the numerous bug reporters and testers!
+</pre>
+<footer>
diff --git a/doc/www.gnu.org/downloads/downloads.wml b/doc/www.gnu.org/downloads/downloads.wml
index e9333aea0..838783472 100644
--- a/doc/www.gnu.org/downloads/downloads.wml
+++ b/doc/www.gnu.org/downloads/downloads.wml
@@ -77,10 +77,10 @@ sub mylink {
<download-block>
<download
- date="06 March 2006"
- version="0.90"
- url="ftp://ftp.gnu.org/gnu/classpath/classpath-0.90.tar.gz"
- notes="http://www.gnu.org/software/classpath/announce/20060306.html"
+ date="15 May 2006"
+ version="0.91"
+ url="ftp://ftp.gnu.org/gnu/classpath/classpath-0.91.tar.gz"
+ notes="http://www.gnu.org/software/classpath/announce/20060515.html"
>
<!-- download
@@ -100,6 +100,12 @@ sub mylink {
<download-block>
<download
+ date="06 March 2006"
+ version="0.90"
+ url="ftp://ftp.gnu.org/gnu/classpath/classpath-0.90.tar.gz"
+ notes="http://www.gnu.org/software/classpath/announce/20060306.html"
+>
+<download
date="13 January 2006"
version="0.20"
url="ftp://ftp.gnu.org/gnu/classpath/classpath-0.20.tar.gz"
diff --git a/doc/www.gnu.org/newsitems.txt b/doc/www.gnu.org/newsitems.txt
index 64577b6f0..df0066500 100644
--- a/doc/www.gnu.org/newsitems.txt
+++ b/doc/www.gnu.org/newsitems.txt
@@ -1,3 +1,8 @@
+<newsitem date="15 May 2006">
+<createlink name="GNU Classpath 0.91"
+ url="announce/20060515.html">
+</newsitem>
+
<newsitem date="06 Mar 2006">
<createlink name="GNU Classpath 0.90"
url="announce/20060306.html">
diff --git a/examples/gnu/classpath/examples/awt/Demo.java b/examples/gnu/classpath/examples/awt/Demo.java
index 64594e47b..5e668dde6 100644
--- a/examples/gnu/classpath/examples/awt/Demo.java
+++ b/examples/gnu/classpath/examples/awt/Demo.java
@@ -154,6 +154,8 @@ class Demo
addSubWindow ("RandomTests", new TestWindow (this));
addSubWindow ("RoundRect", new RoundRectWindow ());
addSubWindow ("Animation", new AnimationWindow ());
+ addSubWindow ("Resolution", new ResolutionWindow ());
+ addSubWindow ("Fullscreen", new FullscreenWindow ());
Panel sp = new Panel();
PrettyPanel p = new PrettyPanel();
@@ -744,6 +746,99 @@ class Demo
t.beep();
}
}
+
+ static class ResolutionWindow extends SubFrame
+ {
+ GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
+
+ public void init ()
+ {
+ initted = true;
+
+ setTitle("Change Screen Resolution");
+ final List list = new List();
+ DisplayMode[] modes = gd.getDisplayModes();
+
+ for (int i=0;i<modes.length;i++ )
+ list.add(modes[i].getWidth() + "x"
+ + modes[i].getHeight()
+ + ((modes[i].getBitDepth() != DisplayMode.BIT_DEPTH_MULTI)
+ ? "x" + modes[i].getBitDepth() + "bpp"
+ : "")
+ + ((modes[i].getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN)
+ ? "@" + modes[i].getRefreshRate() + "Hz"
+ : ""));
+
+ ActionListener al = new ActionListener()
+ {
+ public void actionPerformed(ActionEvent ae)
+ {
+ int i = list.getSelectedIndex();
+ gd.setDisplayMode(gd.getDisplayModes()[i]);
+ }
+ };
+
+ Button b = new Button("Switch");
+ Button c = new Button("Close");
+
+ list.addActionListener(al);
+ b.addActionListener(al);
+
+ c.addActionListener(new ActionListener () {
+ public void actionPerformed (ActionEvent e) {
+ dispose();
+ }
+ });
+
+ setLayout(new GridLayout(3, 1, 5, 5));
+ add(list);
+ add(b);
+ add(c);
+
+ pack();
+ }
+ }
+
+ static class FullscreenWindow extends SubFrame
+ {
+ GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
+
+ public void init ()
+ {
+ initted = true;
+
+ setTitle("Fullscreen Exclusive Mode");
+
+ ActionListener al = new ActionListener()
+ {
+ public void actionPerformed(ActionEvent ae)
+ {
+ if (gd.getFullScreenWindow() == FullscreenWindow.this)
+ gd.setFullScreenWindow(null);
+ else
+ gd.setFullScreenWindow(FullscreenWindow.this);
+ }
+ };
+
+ Button b = new Button("Toggle Fullscreen");
+ Button c = new Button("Close");
+
+ b.addActionListener(al);
+
+ c.addActionListener(new ActionListener () {
+ public void actionPerformed (ActionEvent e) {
+ gd.setFullScreenWindow(null);
+ dispose();
+ }
+ });
+
+ setLayout(new GridLayout(3, 1, 5, 5));
+ add(b);
+ add(c);
+
+ pack();
+ }
+ }
static class RoundRectWindow extends SubFrame
{
diff --git a/examples/gnu/classpath/examples/swing/Demo.java b/examples/gnu/classpath/examples/swing/Demo.java
index 0f0b3555e..6447077a3 100644
--- a/examples/gnu/classpath/examples/swing/Demo.java
+++ b/examples/gnu/classpath/examples/swing/Demo.java
@@ -156,7 +156,10 @@ public class Demo
examples.add(new JMenuItem(new PopupAction("NavigationFilter",
NavigationFilterDemo.createDemoFactory())));
-
+ examples.add(new JMenuItem(new PopupAction("Paint Performance",
+ FillRect.createDemoFactory())));
+
+
final JMenuItem vmMenu;
help.add(new JMenuItem("just play with the widgets"));
@@ -543,7 +546,10 @@ public class Demo
panel.add(new JButton(new PopupAction("Tree",
TreeDemo.createDemoFactory())));
panel.add(new JButton(new PopupAction("Theme Editor",
- MetalThemeEditor.createDemoFactory())));
+ MetalThemeEditor.createDemoFactory())));
+ panel.add(new JButton(new PopupAction("Paint Performance",
+ FillRect.createDemoFactory())));
+
JButton exitDisposer = mkDisposerButton(frame);
panel.add(exitDisposer);
diff --git a/examples/gnu/classpath/examples/swing/FillRect.java b/examples/gnu/classpath/examples/swing/FillRect.java
new file mode 100644
index 000000000..7c6f140a0
--- /dev/null
+++ b/examples/gnu/classpath/examples/swing/FillRect.java
@@ -0,0 +1,388 @@
+/* FillRect.java - demonstrator for classpath/gcj fillrect performance issue
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath examples.
+
+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. */
+
+package gnu.classpath.examples.swing;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+
+/**
+ * @author Norman Hendrich
+ */
+public class FillRect
+ extends JPanel
+ implements ActionListener
+{
+
+ static FillRect fillRectDemo;
+
+ LCDCanvas lcd;
+ Worker worker;
+ JLabel label;
+ JCheckBox translate;
+ JCheckBox lines;
+
+ int nx = 128;
+ int ny = 64;
+ int matrix[][], future[][];
+ int generation = 0;
+
+ // 20 msec, or 50 repaints per sec (theoretically)
+ int sleepMillis = 20;
+ long lastMillis = System.currentTimeMillis();
+
+ boolean enableRepaints = true;
+
+ /**
+ * If true, test translation.
+ */
+ boolean testTranslation = false;
+
+ /**
+ * If true, paint lines rather than rectangles
+ */
+ boolean paintLines;
+
+ public void actionPerformed(ActionEvent e)
+ {
+ if (e.getActionCommand().equals("CLOSE"))
+ {
+ System.exit(0);
+ }
+ }
+
+ public FillRect()
+ {
+ setSize(nx, ny);
+ createContent();
+ }
+
+ public void createContent()
+ {
+ setLayout(new BorderLayout());
+
+ JPanel p = new JPanel(new BorderLayout());
+ lcd = new LCDCanvas();
+ label = new JLabel();
+ label.setText("not running");
+
+ translate = new JCheckBox("translate");
+ translate.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ testTranslation = translate.isSelected();
+ }
+ });
+
+ lines = new JCheckBox("lines");
+ lines.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ paintLines = lines.isSelected();
+ }
+ });
+
+ JPanel bottom = new JPanel();
+ bottom.add(lines);
+ bottom.add(translate);
+
+ p.add(lcd, BorderLayout.CENTER);
+ p.add(bottom, BorderLayout.SOUTH);
+ p.add(label, BorderLayout.NORTH);
+ add(p);
+ }
+
+ public void setSize(int _nx,int _ny )
+ {
+ nx = _nx;
+ ny = _ny;
+ matrix = new int[nx][ny];
+ future = new int[nx][ny];
+ }
+
+ public void initFrameContent()
+ {
+ JPanel closePanel = new JPanel();
+ JButton closeButton = new JButton("Close");
+ closeButton.setActionCommand("CLOSE");
+ closeButton.addActionListener(this);
+ closePanel.add(closeButton);
+ add(closePanel, BorderLayout.SOUTH);
+ }
+
+ public void setSleepMillis(int millis)
+ {
+ sleepMillis = millis;
+ }
+
+ public class LCDCanvas extends JPanel
+ {
+ private int sx, sy;
+ private Color activePixel = new Color(30, 30, 40);
+ private Color passivePixel = new Color(200, 180, 240);
+ private Color gridPixel = new Color(255, 240, 240);
+
+ public LCDCanvas()
+ {
+ super();
+ sx = 4 * nx;
+ sy = 4 * ny;
+ }
+
+ public void paintComponent(Graphics g)
+ {
+ // for buffered drawing - not used atm
+ // g.drawImage( buffer, 0, 0, null );
+ long t1 = System.currentTimeMillis();
+
+ g.setColor(gridPixel);
+ g.fillRect(0, 0, sx, sy);
+
+ Color pixelColor = null;
+
+ int dx, dy;
+
+ if (paintLines)
+ {
+ for (int ix = 0; ix < nx; ix++)
+ for (int iy = 0; iy < ny; iy++)
+ {
+ if (matrix[ix][iy] != 0)
+ pixelColor = activePixel;
+ else
+ pixelColor = passivePixel;
+
+ dx = 4 * ix;
+ dy = 4 * iy;
+ g.setColor(pixelColor);
+
+ if (testTranslation)
+ {
+ g.translate(dx, dy);
+ g.drawLine(0, 0, 5, 5);
+ g.translate(- dx, - dy);
+ }
+ else
+ g.drawLine(dx, dy, dx + 5, dy + 5);
+ }
+ }
+ else
+ for (int ix = 0; ix < nx; ix++)
+ {
+ for (int iy = 0; iy < ny; iy++)
+ {
+ if (matrix[ix][iy] != 0)
+ pixelColor = activePixel;
+ else
+ pixelColor = passivePixel;
+
+ dx = 4 * ix;
+ dy = 4 * iy;
+ g.setColor(pixelColor);
+
+ if (testTranslation)
+ {
+ g.translate(dx, dy);
+ g.fillRect(0, 0, 3, 3);
+ g.translate(- dx, - dy);
+ }
+ else
+ g.fillRect(dx, dy, 3, 3);
+ }
+ }
+
+ long t2 = System.currentTimeMillis();
+
+ label.setText("paintComponent took " + (t2 - t1) + " msec. " + "("
+ + (nx * ny + 1) + " "
+ + (paintLines ? "drawLine" : "fillRect") + " calls)");
+
+ }
+
+ public Dimension getPreferredSize()
+ {
+ return new Dimension(sx,sy);
+ }
+
+ public Dimension getMinimumSize()
+ {
+ return new Dimension(sx,sy);
+ }
+ }
+
+ public class Worker extends Thread
+ {
+ public void run()
+ {
+ boolean running = true;
+ while(running)
+ {
+ iteration();
+
+ if (enableRepaints)
+ display();
+
+ if (sleepMillis > 0)
+ {
+ try
+ {
+ Thread.sleep( sleepMillis );
+ }
+ catch(InterruptedException ie)
+ {
+ running = false;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * stupid animation algorithm: show binary representation of current
+ * iteration.
+ */
+ public void iteration()
+ {
+ generation++;
+
+ for (int i = 0; i < nx; i++)
+ {
+ long tmp1 = 1L << i;
+ for (int j = 0; j < ny; j++)
+ {
+ // count neighbors
+ long tmp2 = (1L << j);
+
+
+ long tmp3 = generation & tmp1 & tmp2;
+ if (tmp3 != 0)
+ matrix[i][j] = 1;
+ else
+ matrix[i][j] = 0;
+ }
+ }
+
+ if ((generation % 100) == 0)
+ {
+ long t = System.currentTimeMillis();
+ // System.out.println(
+ // " generation= " + generation +
+ // " iterations/sec= " + 100.0*1000/(t-lastMillis) );
+ lastMillis = t;
+ }
+ }
+
+ public void display()
+ {
+ lcd.repaint();
+ }
+
+ public static void usage()
+ {
+ System.out.println(
+ "Usage: <java> FillRect2 [-sleep <millis>] [-size <int>] [-nopaint]\n"
+ + "Example: jamvm FillRect2 -sleep 10 -size 100\n"
+ );
+ System.exit(0);
+ }
+
+ public static void main(String args[])
+ throws Exception
+ {
+ fillRectDemo = new FillRect();
+ for (int i = 0; i < args.length; i++)
+ {
+ if ("-help".equals(args[i]))
+ {
+ usage();
+ }
+ if ("-sleep".equals(args[i]))
+ {
+ fillRectDemo.setSleepMillis( Integer.parseInt(args[i + 1]));
+ i++;
+ }
+ if ("-size".equals(args[i]))
+ {
+ int size = Integer.parseInt(args[i + 1]);
+ fillRectDemo.setSize(size, size);
+ i++;
+ }
+ if ("-nopaint".equals(args[i]))
+ {
+ fillRectDemo.enableRepaints = false;
+ }
+ }
+
+ SwingUtilities.invokeLater (new Runnable()
+ {
+ public void run()
+ {
+
+ fillRectDemo.initFrameContent();
+ JFrame frame = new JFrame("FillRect performance test");
+ frame.getContentPane().add(fillRectDemo);
+ frame.pack();
+ frame.show();
+ fillRectDemo.worker = fillRectDemo.new Worker();
+ fillRectDemo.worker.start();
+ }
+ });
+ }
+
+ /**
+ * Returns a DemoFactory that creates a SliderDemo.
+ *
+ * @return a DemoFactory that creates a SliderDemo
+ */
+ public static DemoFactory createDemoFactory()
+ {
+ return new DemoFactory()
+ {
+ public JComponent createDemo()
+ {
+ fillRectDemo = new FillRect();
+ SwingUtilities.invokeLater
+ (new Runnable()
+ {
+ public void run()
+ {
+ fillRectDemo.worker = fillRectDemo.new Worker();
+ fillRectDemo.worker.start();
+ }
+ });
+ return fillRectDemo;
+ }
+ };
+ }
+}
diff --git a/examples/gnu/classpath/examples/swing/NavigationFilterDemo.java b/examples/gnu/classpath/examples/swing/NavigationFilterDemo.java
index 6c1be74cc..5184e5ba0 100644
--- a/examples/gnu/classpath/examples/swing/NavigationFilterDemo.java
+++ b/examples/gnu/classpath/examples/swing/NavigationFilterDemo.java
@@ -160,7 +160,7 @@ public class NavigationFilterDemo
pt = text.getCaret().getMagicCaretPosition();
// Calculate its position above.
- newpos = Utilities.getPositionAbove(text, pos, pt.x);
+ newpos = Utilities.getPositionAbove(text, pos, (pt != null) ? pt.x : 0);
// If we have a valid position, then calculate the next word start
// from there.
@@ -173,7 +173,7 @@ public class NavigationFilterDemo
pt = text.getCaret().getMagicCaretPosition();
// Calculate its position below.
- newpos = Utilities.getPositionBelow(text, pos, pt.x);
+ newpos = Utilities.getPositionBelow(text, pos, (pt != null) ? pt.x : 0);
// If we have a valid position, then calculate the next word start
// from there.
@@ -192,7 +192,6 @@ public class NavigationFilterDemo
else
return Utilities.getPreviousWord(text, newpos);
case SwingConstants.EAST:
- // Simply calculate the next word's start offset.
return Utilities.getNextWord(text, newpos);
default:
// Do whatever the super implementation did.
diff --git a/examples/gnu/classpath/examples/swing/TableDemo.java b/examples/gnu/classpath/examples/swing/TableDemo.java
index e661ee3ad..d4a97b3ef 100644
--- a/examples/gnu/classpath/examples/swing/TableDemo.java
+++ b/examples/gnu/classpath/examples/swing/TableDemo.java
@@ -39,19 +39,36 @@ exception statement from your version. */
package gnu.classpath.examples.swing;
import java.awt.BorderLayout;
+import java.awt.Component;
import java.awt.Dimension;
+import java.awt.Rectangle;
+import java.text.DateFormat;
+import java.util.Date;
+import javax.swing.AbstractCellEditor;
+import javax.swing.BorderFactory;
+import javax.swing.DefaultCellEditor;
+import javax.swing.DefaultListCellRenderer;
import javax.swing.Icon;
+import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
+import javax.swing.JList;
import javax.swing.JPanel;
+import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
+import javax.swing.JSlider;
import javax.swing.JTable;
+import javax.swing.JTextField;
import javax.swing.SwingUtilities;
+import javax.swing.border.Border;
import javax.swing.plaf.metal.MetalIconFactory;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.DefaultTableModel;
+import javax.swing.table.TableCellEditor;
+import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
+import javax.swing.table.TableColumnModel;
/**
* Displays the editable table. The first column consists of check boxes.
@@ -78,12 +95,11 @@ public class TableDemo extends JPanel
{
/**
- * Return true if the cell is editable.
- * Icons are not editable, other cells are editable.
+ * All cells are editable in our table.
*/
public boolean isCellEditable(int row, int column)
{
- return column!=1;
+ return true;
}
/**
@@ -144,6 +160,77 @@ public class TableDemo extends JPanel
}
/**
+ * The scroll bar renderer.
+ */
+ class SliderCell
+ extends AbstractCellEditor
+ implements TableCellEditor, TableCellRenderer
+ {
+ /**
+ * The editor bar.
+ */
+ JSlider bar;
+
+ /**
+ * The renderer bar.
+ */
+ JSlider rendererBar;
+
+ /**
+ * The border around the bar, if required.
+ */
+ Border border = BorderFactory.createLineBorder(table.getGridColor());
+
+ SliderCell()
+ {
+ bar = new JSlider();
+ bar.setOrientation(JScrollBar.HORIZONTAL);
+ bar.setMinimum(0);
+ bar.setMaximum(rows);
+ bar.setBorder(border);
+
+ rendererBar = new JSlider();
+ rendererBar.setMinimum(0);
+ rendererBar.setMaximum(rows);
+ rendererBar.setEnabled(false);
+ }
+
+ /**
+ * Get the editor.
+ */
+ public Component getTableCellEditorComponent(JTable table, Object value,
+ boolean isSelected, int row,
+ int column)
+ {
+ if (value instanceof Integer)
+ bar.setValue(((Integer) value).intValue());
+ return bar;
+ }
+
+ /**
+ * Get the renderer.
+ */
+ public Component getTableCellRendererComponent(JTable table, Object value,
+ boolean isSelected,
+ boolean hasFocus, int row,
+ int column)
+ {
+ rendererBar.setValue(((Integer) value).intValue());
+ if (hasFocus)
+ rendererBar.setBorder(border);
+ else
+ rendererBar.setBorder(null);
+ return rendererBar;
+ }
+
+ public Object getCellEditorValue()
+ {
+ return new Integer(bar.getValue());
+ }
+
+ }
+
+ /**
* The table being displayed.
*/
JTable table = new JTable();
@@ -159,6 +246,25 @@ public class TableDemo extends JPanel
Object[][] values;
/**
+ * The icons that appear in the icon column.
+ */
+ Icon[] icons = new Icon[]
+ {
+ MetalIconFactory.getTreeComputerIcon(),
+ MetalIconFactory.getTreeHardDriveIcon(),
+ MetalIconFactory.getTreeFolderIcon(),
+ };
+
+ /**
+ * The choices in the combo boxes
+ */
+ String [] sides = new String[]
+ {
+ "north", "south", "east", "west"
+ };
+
+
+ /**
* Create the table demo with the given titel.
*/
public TableDemo()
@@ -178,29 +284,25 @@ public class TableDemo extends JPanel
setLayout(new BorderLayout());
values = new Object[rows][];
- // The icons that appear in the icon column.
- Icon[] icons = new Icon[]
- {
- MetalIconFactory.getTreeComputerIcon(),
- MetalIconFactory.getTreeHardDriveIcon(),
- MetalIconFactory.getTreeFolderIcon(),
- };
-
for (int i = 0; i < values.length; i++)
{
values[i] = new Object[cols];
- for (int j = 2; j < cols; j++)
+ for (int j = 3; j < cols; j++)
{
values[i][j] = "" + ((char) ('a' + j)) + i;
}
values [i][0] = i % 2 == 0? Boolean.TRUE : Boolean.FALSE;
- values [i][1] = icons [ i % icons.length ];
+ values [i][1] = icons [ i % icons.length ];
+ values [i][2] = sides [ i % sides.length ];
+ values [i][4] = new Integer(i);
}
table.setModel(model);
// Make the columns with gradually increasing width:
DefaultTableColumnModel cm = new DefaultTableColumnModel();
+ table.setColumnModel(cm);
+
for (int i = 0; i < cols; i++)
{
TableColumn column = new TableColumn(i);
@@ -215,8 +317,9 @@ public class TableDemo extends JPanel
cm.addColumn(column);
}
-
- table.setColumnModel(cm);
+
+ setCustomEditors();
+ setInformativeHeaders();
// Create the table, place it into scroll pane and place
// the pane into this frame.
@@ -226,6 +329,52 @@ public class TableDemo extends JPanel
scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scroll.getViewport().add(table);
add(scroll, BorderLayout.CENTER);
+
+ // Increase the row height to make the icons and sliders look better.
+ table.setRowHeight(table.getRowHeight()+2);
+ }
+
+ /**
+ * Set the more informative column headers for specific columns.
+ */
+ void setInformativeHeaders()
+ {
+ TableColumnModel cm = table.getColumnModel();
+
+ cm.getColumn(0).setHeaderValue("check");
+ cm.getColumn(1).setHeaderValue("icon");
+ cm.getColumn(2).setHeaderValue("combo");
+ cm.getColumn(3).setHeaderValue("edit combo");
+ cm.getColumn(4).setHeaderValue("slider");
+ }
+
+ /**
+ * Set the custom editors for combo boxes. This method also sets one
+ * custom renderer.
+ */
+ void setCustomEditors()
+ {
+ TableColumnModel cm = table.getColumnModel();
+
+ // Set combo-box based editor for icons (note that no custom
+ // renderer is needed for JComboBox to work with icons.
+ JComboBox combo0 = new JComboBox(icons);
+ cm.getColumn(1).setCellEditor(new DefaultCellEditor(combo0));
+
+ // Set the simple combo box editor for the third column:
+ JComboBox combo1 = new JComboBox(sides);
+ cm.getColumn(2).setCellEditor(new DefaultCellEditor(combo1));
+
+ // Set the editable combo box for the forth column:
+ JComboBox combo2 = new JComboBox(sides);
+ combo2.setEditable(true);
+ cm.getColumn(3).setCellEditor(new DefaultCellEditor(combo2));
+
+ SliderCell scrollView = new SliderCell();
+ cm.getColumn(4).setCellEditor(scrollView);
+ cm.getColumn(4).setCellRenderer(scrollView);
+
+ table.setColumnModel(cm);
}
/**
@@ -266,3 +415,4 @@ public class TableDemo extends JPanel
};
}
}
+
diff --git a/gnu/classpath/Configuration.java.in b/gnu/classpath/Configuration.java.in
index 569ccf541..7f490d529 100644
--- a/gnu/classpath/Configuration.java.in
+++ b/gnu/classpath/Configuration.java.in
@@ -95,10 +95,4 @@ public interface Configuration
*/
boolean JAVA_LANG_SYSTEM_EXPLICIT_INITIALIZATION =
@JAVA_LANG_SYSTEM_EXPLICIT_INITIALIZATION@;
-
- /**
- * Set to true if Cairo was found and enabled during configure,
- * false otherwise.
- */
- boolean GTK_CAIRO_ENABLED = @GTK_CAIRO_ENABLED@;
}
diff --git a/gnu/classpath/jdwp/processor/ClassTypeCommandSet.java b/gnu/classpath/jdwp/processor/ClassTypeCommandSet.java
index f60da7b70..a3a7ca05e 100644
--- a/gnu/classpath/jdwp/processor/ClassTypeCommandSet.java
+++ b/gnu/classpath/jdwp/processor/ClassTypeCommandSet.java
@@ -106,8 +106,12 @@ public class ClassTypeCommandSet
Class clazz = refId.getType();
Class superClazz = clazz.getSuperclass();
- ReferenceTypeId clazzId = idMan.getReferenceTypeId(superClazz);
- clazzId.write(os);
+ if (superClazz == null) {
+ os.writeLong(0L);
+ } else {
+ ReferenceTypeId clazzId = idMan.getReferenceTypeId(superClazz);
+ clazzId.write(os);
+ }
}
private void executeSetValues(ByteBuffer bb, DataOutputStream os)
diff --git a/gnu/classpath/jdwp/processor/EventRequestCommandSet.java b/gnu/classpath/jdwp/processor/EventRequestCommandSet.java
index e4b1b602e..59cfb94d3 100644
--- a/gnu/classpath/jdwp/processor/EventRequestCommandSet.java
+++ b/gnu/classpath/jdwp/processor/EventRequestCommandSet.java
@@ -147,7 +147,7 @@ public class EventRequestCommandSet
if (id == 0)
refId = null;
else
- refId = idMan.readReferenceTypeId(bb);
+ refId = idMan.getReferenceType(id);
boolean caught = (bb.get() == 0) ? false : true;
boolean unCaught = (bb.get() == 0) ? false : true;
filter = new ExceptionOnlyFilter(refId, caught, unCaught);
diff --git a/gnu/classpath/jdwp/processor/ThreadGroupReferenceCommandSet.java b/gnu/classpath/jdwp/processor/ThreadGroupReferenceCommandSet.java
index ba36251f6..103199a2b 100644
--- a/gnu/classpath/jdwp/processor/ThreadGroupReferenceCommandSet.java
+++ b/gnu/classpath/jdwp/processor/ThreadGroupReferenceCommandSet.java
@@ -103,8 +103,12 @@ public class ThreadGroupReferenceCommandSet
ObjectId oid = idMan.readObjectId(bb);
ThreadGroup group = (ThreadGroup) oid.getObject();
ThreadGroup parent = group.getParent();
- ObjectId parentId = idMan.getObjectId(parent);
- parentId.write(os);
+ if (parent == null) {
+ os.writeLong(0L);
+ } else {
+ ObjectId parentId = idMan.getObjectId(parent);
+ parentId.write(os);
+ }
}
private void executeChildren(ByteBuffer bb, DataOutputStream os)
diff --git a/gnu/java/awt/BitwiseXORComposite.java b/gnu/java/awt/BitwiseXORComposite.java
index b568e1108..9205df1dd 100644
--- a/gnu/java/awt/BitwiseXORComposite.java
+++ b/gnu/java/awt/BitwiseXORComposite.java
@@ -59,7 +59,7 @@ import java.awt.image.WritableRaster;
* />
*
* <p>The above screen shot shows the result of applying six different
- * BitwiseXORComposites. They were constructed with the colors colors
+ * BitwiseXORComposites. They were constructed with the colors
* white, blue, black, orange, green, and brown, respectively. Each
* composite was used to paint a fully white rectangle on top of the
* blue bar in the background.
diff --git a/gnu/java/awt/Buffers.java b/gnu/java/awt/Buffers.java
index c6ccf9191..2015634bb 100644
--- a/gnu/java/awt/Buffers.java
+++ b/gnu/java/awt/Buffers.java
@@ -144,25 +144,7 @@ public final class Buffers
*/
public static Object getData(DataBuffer buffer)
{
- if (buffer instanceof DataBufferByte)
- return ((DataBufferByte) buffer).getData();
-
- if (buffer instanceof DataBufferShort)
- return ((DataBufferShort) buffer).getData();
-
- if (buffer instanceof DataBufferUShort)
- return ((DataBufferUShort) buffer).getData();
-
- if (buffer instanceof DataBufferInt)
- return ((DataBufferInt) buffer).getData();
-
- if (buffer instanceof DataBufferFloat)
- return ((DataBufferFloat) buffer).getData();
-
- if (buffer instanceof DataBufferDouble)
- return ((DataBufferDouble) buffer).getData();
-
- throw new ClassCastException("Unknown data buffer type");
+ return getData(buffer, 0, null, 0, buffer.getSize());
}
@@ -172,46 +154,46 @@ public final class Buffers
* given destination array is null.
*/
public static Object getData(DataBuffer src, int srcOffset,
- Object dest, int destOffset,
+ Object dest, int dstOffset,
int length)
{
Object from;
- if (src instanceof DataBufferByte)
- {
- from = ((DataBufferByte) src).getData();
- if (dest == null) dest = new byte[length+destOffset];
- }
- else if (src instanceof DataBufferShort)
- {
- from = ((DataBufferShort) src).getData();
- if (dest == null) dest = new short[length+destOffset];
- }
- else if (src instanceof DataBufferUShort)
- {
- from = ((DataBufferUShort) src).getData();
- if (dest == null) dest = new short[length+destOffset];
- }
- else if (src instanceof DataBufferInt)
- {
- from = ((DataBufferInt) src).getData();
- if (dest == null) dest = new int[length+destOffset];
- }
- else if (src instanceof DataBufferFloat)
- {
- from = ((DataBufferFloat) src).getData();
- if (dest == null) dest = new float[length+destOffset];
- }
- else if (src instanceof DataBufferDouble)
- {
- from = ((DataBufferDouble) src).getData();
- if (dest == null) dest = new double[length+destOffset];
- }
- else
+ switch(src.getDataType())
{
+ case DataBuffer.TYPE_BYTE:
+ if (dest == null) dest = new byte[length+dstOffset];
+ for(int i = 0; i < length; i++)
+ ((byte[])dest)[i + dstOffset] = (byte)src.getElem(i + srcOffset);
+ break;
+
+ case DataBuffer.TYPE_DOUBLE:
+ if (dest == null) dest = new double[length+dstOffset];
+ for(int i = 0; i < length; i++)
+ ((double[])dest)[i + dstOffset] = src.getElemDouble(i + srcOffset);
+ break;
+
+ case DataBuffer.TYPE_FLOAT:
+ if (dest == null) dest = new float[length+dstOffset];
+ for(int i = 0; i < length; i++)
+ ((float[])dest)[i + dstOffset] = src.getElemFloat(i + srcOffset);
+ break;
+
+ case DataBuffer.TYPE_INT:
+ if (dest == null) dest = new int[length+dstOffset];
+ for(int i = 0; i < length; i++)
+ ((int[])dest)[i + dstOffset] = src.getElem(i + srcOffset);
+ break;
+
+ case DataBuffer.TYPE_SHORT:
+ case DataBuffer.TYPE_USHORT:
+ if (dest == null) dest = new short[length+dstOffset];
+ for(int i = 0; i < length; i++)
+ ((short[])dest)[i + dstOffset] = (short)src.getElem(i + srcOffset);
+ break;
+
+ case DataBuffer.TYPE_UNDEFINED:
throw new ClassCastException("Unknown data buffer type");
}
-
- System.arraycopy(from, srcOffset, dest, destOffset, length);
return dest;
}
diff --git a/gnu/java/awt/font/GNUGlyphVector.java b/gnu/java/awt/font/GNUGlyphVector.java
index 9688698de..f17a45113 100644
--- a/gnu/java/awt/font/GNUGlyphVector.java
+++ b/gnu/java/awt/font/GNUGlyphVector.java
@@ -110,7 +110,7 @@ public class GNUGlyphVector
fontSize = font.getSize2D();
transform = font.getTransform(); // returns a modifiable copy
- transform.concatenate(renderContext.getTransform());
+ //transform.concatenate(renderContext.getTransform());
}
diff --git a/gnu/java/awt/font/opentype/NameDecoder.java b/gnu/java/awt/font/opentype/NameDecoder.java
index bc0c0df09..e4ea202bb 100644
--- a/gnu/java/awt/font/opentype/NameDecoder.java
+++ b/gnu/java/awt/font/opentype/NameDecoder.java
@@ -48,7 +48,7 @@ import java.util.Locale;
*
* @author Sascha Brawer (brawer@dandelis.ch)
*/
-class NameDecoder
+public class NameDecoder
{
public static final int NAME_COPYRIGHT = 0;
@@ -122,27 +122,38 @@ class NameDecoder
nameTable.position(0);
/* We understand only format 0 of the name table. */
- if (nameTable.getChar() != 0)
+ if (nameTable.getShort() != 0)
return null;
macLanguage = getMacLanguageCode(locale);
msLanguage = getMicrosoftLanguageCode(locale);
- numRecords = nameTable.getChar();
- offset = nameTable.getChar();
+ numRecords = nameTable.getShort();
+ offset = nameTable.getShort();
for (int i = 0; i < numRecords; i++)
{
- namePlatform = nameTable.getChar();
- nameEncoding = nameTable.getChar();
- nameLanguage = nameTable.getChar();
- nameID = nameTable.getChar();
- nameLen = nameTable.getChar();
- nameStart = offset + nameTable.getChar();
+ namePlatform = nameTable.getShort();
+ nameEncoding = nameTable.getShort();
+ nameLanguage = nameTable.getShort();
+ nameID = nameTable.getShort();
+ nameLen = nameTable.getShort();
+ nameStart = offset + nameTable.getShort();
if (nameID != name)
continue;
+ // Handle PS seperately as it can be only ASCII, although
+ // possibly encoded as UTF-16BE
+ if ( name == NAME_POSTSCRIPT )
+ {
+ if( nameTable.get(nameStart) == 0 ) // Peek at top byte
+ result = decodeName("UTF-16BE", nameTable, nameStart, nameLen);
+ else
+ result = decodeName("ASCII", nameTable, nameStart, nameLen);
+ return result;
+ }
+
match = false;
switch (namePlatform)
{
@@ -393,14 +404,19 @@ class NameDecoder
private static String decodeName(int platform, int encoding, int language,
ByteBuffer buffer, int offset, int len)
{
- byte[] byteBuf;
- String charsetName;
- int oldPosition;
-
- charsetName = getCharsetName(platform, language, encoding);
+ String charsetName = getCharsetName(platform, language, encoding);
if (charsetName == null)
return null;
+ return decodeName(charsetName, buffer, offset, len);
+ }
+
+ private static String decodeName(String charsetName,
+ ByteBuffer buffer, int offset, int len)
+ {
+ byte[] byteBuf;
+ int oldPosition;
+
byteBuf = new byte[len];
oldPosition = buffer.position();
try
diff --git a/gnu/java/awt/java2d/AbstractGraphics2D.java b/gnu/java/awt/java2d/AbstractGraphics2D.java
index e55d317fd..7df9949e6 100644
--- a/gnu/java/awt/java2d/AbstractGraphics2D.java
+++ b/gnu/java/awt/java2d/AbstractGraphics2D.java
@@ -84,7 +84,48 @@ import java.util.Iterator;
import java.util.Map;
/**
- * Implements general and shared behaviour for Graphics2D implementation.
+ * This is a 100% Java implementation of the Java2D rendering pipeline. It is
+ * meant as a base class for Graphics2D implementations.
+ *
+ * <h2>Backend interface</h2>
+ * <p>
+ * The backend must at the very least provide a Raster which the the rendering
+ * pipeline can paint into. This must be implemented in
+ * {@link #getDestinationRaster()}. For some backends that might be enough, like
+ * when the target surface can be directly access via the raster (like in
+ * BufferedImages). Other targets need some way to synchronize the raster with
+ * the surface, which can be achieved by implementing the
+ * {@link #updateRaster(Raster, int, int, int, int)} method, which always gets
+ * called after a chunk of data got painted into the raster.
+ * </p>
+ * <p>The backend is free to provide implementations for the various raw*
+ * methods for optimized AWT 1.1 style painting of some primitives. This should
+ * accelerate painting of Swing greatly. When doing so, the backend must also
+ * keep track of the clip and translation, probably by overriding
+ * some clip and translate methods. Don't forget to message super in such a
+ * case.</p>
+ *
+ * <h2>Acceleration options</h2>
+ * <p>
+ * The fact that it is
+ * pure Java makes it a little slow. However, there are several ways of
+ * accelerating the rendering pipeline:
+ * <ol>
+ * <li><em>Optimization hooks for AWT 1.1 - like graphics operations.</em>
+ * The most important methods from the {@link java.awt.Graphics} class
+ * have a corresponding <code>raw*</code> method, which get called when
+ * several optimization conditions are fullfilled. These conditions are
+ * described below. Subclasses can override these methods and delegate
+ * it directly to a native backend.</li>
+ * <li><em>Native PaintContexts and CompositeContext.</em> The implementations
+ * for the 3 PaintContexts and AlphaCompositeContext can be accelerated
+ * using native code. These have proved to two of the most performance
+ * critical points in the rendering pipeline and cannot really be done quickly
+ * in plain Java because they involve lots of shuffling around with large
+ * arrays. In fact, you really would want to let the graphics card to the
+ * work, they are made for this.</li>
+ * </ol>
+ * </p>
*
* @author Roman Kennke (kennke@aicas.com)
*/
@@ -146,11 +187,6 @@ public abstract class AbstractGraphics2D
private Raster paintRaster;
/**
- * A cached pixel array.
- */
- private int[] pixel;
-
- /**
* The raster of the destination surface. This is where the painting is
* performed.
*/
@@ -168,7 +204,7 @@ public abstract class AbstractGraphics2D
private transient ArrayList[] edgeTable;
/**
- * Indicates if cerain graphics primitives can be rendered in an optimized
+ * Indicates if certain graphics primitives can be rendered in an optimized
* fashion. This will be the case if the following conditions are met:
* - The transform may only be a translation, no rotation, shearing or
* scaling.
@@ -198,8 +234,6 @@ public abstract class AbstractGraphics2D
hints.put(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_DEFAULT);
renderingHints = new RenderingHints(hints);
-
- pixel = new int[4];
}
/**
@@ -212,40 +246,211 @@ public abstract class AbstractGraphics2D
{
// Stroke the shape.
Shape strokedShape = stroke.createStrokedShape(shape);
-
- // Clip the stroked shape.
-// Shape clipped = clipShape(strokedShape);
-// if (clipped != null)
-// {
-// // Fill the shape.
-// fillShape(clipped, false);
-// }
- // FIXME: Clipping doesn't seem to work.
+ // Fill the stroked shape.
fillShape(strokedShape, false);
}
- public boolean drawImage(Image image, AffineTransform xform, ImageObserver obs)
+
+ /**
+ * Draws the specified image and apply the transform for image space ->
+ * user space conversion.
+ *
+ * This method is implemented to special case RenderableImages and
+ * RenderedImages and delegate to
+ * {@link #drawRenderableImage(RenderableImage, AffineTransform)} and
+ * {@link #drawRenderedImage(RenderedImage, AffineTransform)} accordingly.
+ * Other image types are not yet handled.
+ *
+ * @param image the image to be rendered
+ * @param xform the transform from image space to user space
+ * @param obs the image observer to be notified
+ */
+ public boolean drawImage(Image image, AffineTransform xform,
+ ImageObserver obs)
{
- // FIXME: Implement this.
- throw new UnsupportedOperationException("Not yet implemented");
+ boolean ret = false;
+ Rectangle areaOfInterest = new Rectangle(0, 0, image.getWidth(obs),
+ image.getHeight(obs));
+ return drawImageImpl(image, xform, obs, areaOfInterest);
+ }
+
+ /**
+ * Draws the specified image and apply the transform for image space ->
+ * user space conversion. This method only draw the part of the image
+ * specified by <code>areaOfInterest</code>.
+ *
+ * This method is implemented to special case RenderableImages and
+ * RenderedImages and delegate to
+ * {@link #drawRenderableImage(RenderableImage, AffineTransform)} and
+ * {@link #drawRenderedImage(RenderedImage, AffineTransform)} accordingly.
+ * Other image types are not yet handled.
+ *
+ * @param image the image to be rendered
+ * @param xform the transform from image space to user space
+ * @param obs the image observer to be notified
+ * @param areaOfInterest the area in image space that is rendered
+ */
+ private boolean drawImageImpl(Image image, AffineTransform xform,
+ ImageObserver obs, Rectangle areaOfInterest)
+ {
+ boolean ret;
+ if (image == null)
+ {
+ ret = true;
+ }
+ else if (image instanceof RenderedImage)
+ {
+ // FIXME: Handle the ImageObserver.
+ drawRenderedImageImpl((RenderedImage) image, xform, areaOfInterest);
+ ret = true;
+ }
+ else if (image instanceof RenderableImage)
+ {
+ // FIXME: Handle the ImageObserver.
+ drawRenderableImageImpl((RenderableImage) image, xform, areaOfInterest);
+ ret = true;
+ }
+ else
+ {
+ // FIXME: Implement rendering of other Image types.
+ ret = false;
+ }
+ return ret;
}
+ /**
+ * Renders a BufferedImage and applies the specified BufferedImageOp before
+ * to filter the BufferedImage somehow. The resulting BufferedImage is then
+ * passed on to {@link #drawRenderedImage(RenderedImage, AffineTransform)}
+ * to perform the final rendering.
+ *
+ * @param image the source buffered image
+ * @param op the filter to apply to the buffered image before rendering
+ * @param x the x coordinate to render the image to
+ * @param y the y coordinate to render the image to
+ */
public void drawImage(BufferedImage image, BufferedImageOp op, int x, int y)
{
- // FIXME: Implement this.
- throw new UnsupportedOperationException("Not yet implemented");
+ BufferedImage filtered =
+ op.createCompatibleDestImage(image, image.getColorModel());
+ AffineTransform t = new AffineTransform();
+ t.translate(x, y);
+ drawRenderedImage(filtered, t);
}
+ /**
+ * Renders the specified image to the destination raster. The specified
+ * transform is used to convert the image into user space. The transform
+ * of this AbstractGraphics2D object is used to transform from user space
+ * to device space.
+ *
+ * The rendering is performed using the scanline algorithm that performs the
+ * rendering of other shapes and a custom Paint implementation, that supplies
+ * the pixel values of the rendered image.
+ *
+ * @param image the image to render to the destination raster
+ * @param xform the transform from image space to user space
+ */
public void drawRenderedImage(RenderedImage image, AffineTransform xform)
{
- // FIXME: Implement this.
- throw new UnsupportedOperationException("Not yet implemented");
+ Rectangle areaOfInterest = new Rectangle(image.getMinX(),
+ image.getHeight(),
+ image.getWidth(),
+ image.getHeight());
+ drawRenderedImageImpl(image, xform, areaOfInterest);
}
+ /**
+ * Renders the specified image to the destination raster. The specified
+ * transform is used to convert the image into user space. The transform
+ * of this AbstractGraphics2D object is used to transform from user space
+ * to device space. Only the area specified by <code>areaOfInterest</code>
+ * is finally rendered to the target.
+ *
+ * The rendering is performed using the scanline algorithm that performs the
+ * rendering of other shapes and a custom Paint implementation, that supplies
+ * the pixel values of the rendered image.
+ *
+ * @param image the image to render to the destination raster
+ * @param xform the transform from image space to user space
+ */
+ private void drawRenderedImageImpl(RenderedImage image,
+ AffineTransform xform,
+ Rectangle areaOfInterest)
+ {
+ // First we compute the transformation. This is made up of 3 parts:
+ // 1. The areaOfInterest -> image space transform.
+ // 2. The image space -> user space transform.
+ // 3. The user space -> device space transform.
+ AffineTransform t = new AffineTransform();
+ t.translate(- areaOfInterest.x - image.getMinX(),
+ - areaOfInterest.y - image.getMinY());
+ t.concatenate(xform);
+ t.concatenate(transform);
+ AffineTransform it = null;
+ try
+ {
+ it = t.createInverse();
+ }
+ catch (NoninvertibleTransformException ex)
+ {
+ // Ignore -- we return if the transform is not invertible.
+ }
+ if (it != null)
+ {
+ // Transform the area of interest into user space.
+ GeneralPath aoi = new GeneralPath(areaOfInterest);
+ aoi.transform(xform);
+ // Render the shape using the standard renderer, but with a temporary
+ // ImagePaint.
+ ImagePaint p = new ImagePaint(image, it);
+ Paint savedPaint = paint;
+ try
+ {
+ paint = p;
+ fillShape(aoi, false);
+ }
+ finally
+ {
+ paint = savedPaint;
+ }
+ }
+ }
+
+ /**
+ * Renders a renderable image. This produces a RenderedImage, which is
+ * then passed to {@link #drawRenderedImage(RenderedImage, AffineTransform)}
+ * to perform the final rendering.
+ *
+ * @param image the renderable image to be rendered
+ * @param xform the transform from image space to user space
+ */
public void drawRenderableImage(RenderableImage image, AffineTransform xform)
{
- // FIXME: Implement this.
- throw new UnsupportedOperationException("Not yet implemented");
+ Rectangle areaOfInterest = new Rectangle((int) image.getMinX(),
+ (int) image.getHeight(),
+ (int) image.getWidth(),
+ (int) image.getHeight());
+ drawRenderableImageImpl(image, xform, areaOfInterest);
+
+ }
+
+ /**
+ * Renders a renderable image. This produces a RenderedImage, which is
+ * then passed to {@link #drawRenderedImage(RenderedImage, AffineTransform)}
+ * to perform the final rendering. Only the area of the image specified
+ * by <code>areaOfInterest</code> is rendered.
+ *
+ * @param image the renderable image to be rendered
+ * @param xform the transform from image space to user space
+ */
+ private void drawRenderableImageImpl(RenderableImage image,
+ AffineTransform xform,
+ Rectangle areaOfInterest)
+ {
+ // TODO: Maybe make more clever usage of a RenderContext here.
+ RenderedImage rendered = image.createDefaultRendering();
+ drawRenderedImageImpl(rendered, xform, areaOfInterest);
}
/**
@@ -257,9 +462,14 @@ public abstract class AbstractGraphics2D
*/
public void drawString(String text, int x, int y)
{
- FontRenderContext ctx = getFontRenderContext();
- GlyphVector gv = font.createGlyphVector(ctx, text.toCharArray());
- drawGlyphVector(gv, x, y);
+ if (isOptimized)
+ rawDrawString(text, x, y);
+ else
+ {
+ FontRenderContext ctx = getFontRenderContext();
+ GlyphVector gv = font.createGlyphVector(ctx, text.toCharArray());
+ drawGlyphVector(gv, x, y);
+ }
}
/**
@@ -352,7 +562,6 @@ public abstract class AbstractGraphics2D
else
{
updateOptimization();
- rawSetForeground((Color) paint);
}
}
}
@@ -534,7 +743,7 @@ public abstract class AbstractGraphics2D
if (clip != null)
{
AffineTransform clipTransform = new AffineTransform();
- clipTransform.scale(-scaleX, -scaleY);
+ clipTransform.scale(1 / scaleX, 1 / scaleY);
updateClip(clipTransform);
}
updateOptimization();
@@ -709,8 +918,7 @@ public abstract class AbstractGraphics2D
public FontRenderContext getFontRenderContext()
{
- //return new FontRenderContext(transform, false, false);
- return new FontRenderContext(new AffineTransform(), false, false);
+ return new FontRenderContext(transform, false, true);
}
/**
@@ -723,22 +931,15 @@ public abstract class AbstractGraphics2D
public void drawGlyphVector(GlyphVector gv, float x, float y)
{
int numGlyphs = gv.getNumGlyphs();
- AffineTransform t = new AffineTransform();
- t.translate(x, y);
-
-// // TODO: We could use fill(gv.getOutline()), but that seems to be
- // slightly more inefficient.
+ translate(x, y);
+ // TODO: We could use fill(gv.getOutline()), but that seems to be
+ // slightly more inefficient.
for (int i = 0; i < numGlyphs; i++)
{
- //fill(gv.getGlyphVisualBounds(i));
- GeneralPath p = new GeneralPath(gv.getGlyphOutline(i));
- p.transform(t);
- //Shape clipped = clipShape(p);
- //if (clipped != null)
- // fillShape(clipped, true);
- // FIXME: Clipping doesn't seem to work correctly.
- fillShape(p, true);
+ Shape o = gv.getGlyphOutline(i);
+ fillShape(o, true);
}
+ translate(-x, -y);
}
/**
@@ -915,8 +1116,10 @@ public abstract class AbstractGraphics2D
public void copyArea(int x, int y, int width, int height, int dx, int dy)
{
- // FIXME: Implement this.
- throw new UnsupportedOperationException("Not yet implemented");
+ if (isOptimized)
+ rawCopyArea(x, y, width, height, dx, dy);
+ else
+ copyAreaImpl(x, y, width, height, dx, dy);
}
/**
@@ -975,11 +1178,15 @@ public abstract class AbstractGraphics2D
*/
public void clearRect(int x, int y, int width, int height)
{
- Paint savedForeground = getPaint();
- setPaint(getBackground());
- //System.err.println("clearRect transform type: " + transform.getType());
- fillRect(x, y, width, height);
- setPaint(savedForeground);
+ if (isOptimized)
+ rawClearRect(x, y, width, height);
+ else
+ {
+ Paint savedForeground = getPaint();
+ setPaint(getBackground());
+ fillRect(x, y, width, height);
+ setPaint(savedForeground);
+ }
}
/**
@@ -1084,47 +1291,153 @@ public abstract class AbstractGraphics2D
fill(new Polygon(xPoints, yPoints, npoints));
}
+ /**
+ * Draws the specified image at the specified location. This forwards
+ * to {@link #drawImage(Image, AffineTransform, ImageObserver)}.
+ *
+ * @param image the image to render
+ * @param x the x location to render to
+ * @param y the y location to render to
+ * @param observer the image observer to receive notification
+ */
public boolean drawImage(Image image, int x, int y, ImageObserver observer)
{
- // FIXME: Implement this.
- throw new UnsupportedOperationException("Not yet implemented");
+ boolean ret;
+ if (isOptimized)
+ ret = rawDrawImage(image, x, y, observer);
+ else
+ {
+ AffineTransform t = new AffineTransform();
+ t.translate(x, y);
+ ret = drawImage(image, t, observer);
+ }
+ return ret;
}
+ /**
+ * Draws the specified image at the specified location. The image
+ * is scaled to the specified width and height. This forwards
+ * to {@link #drawImage(Image, AffineTransform, ImageObserver)}.
+ *
+ * @param image the image to render
+ * @param x the x location to render to
+ * @param y the y location to render to
+ * @param width the target width of the image
+ * @param height the target height of the image
+ * @param observer the image observer to receive notification
+ */
public boolean drawImage(Image image, int x, int y, int width, int height,
ImageObserver observer)
{
- // FIXME: Implement this.
- throw new UnsupportedOperationException("Not yet implemented");
+ AffineTransform t = new AffineTransform();
+ t.translate(x, y);
+ double scaleX = (double) image.getWidth(observer) / (double) width;
+ double scaleY = (double) image.getHeight(observer) / (double) height;
+ t.scale(scaleX, scaleY);
+ return drawImage(image, t, observer);
}
+ /**
+ * Draws the specified image at the specified location. This forwards
+ * to {@link #drawImage(Image, AffineTransform, ImageObserver)}.
+ *
+ * @param image the image to render
+ * @param x the x location to render to
+ * @param y the y location to render to
+ * @param bgcolor the background color to use for transparent pixels
+ * @param observer the image observer to receive notification
+ */
public boolean drawImage(Image image, int x, int y, Color bgcolor,
ImageObserver observer)
{
- // FIXME: Implement this.
- throw new UnsupportedOperationException("Not yet implemented");
+ AffineTransform t = new AffineTransform();
+ t.translate(x, y);
+ // TODO: Somehow implement the background option.
+ return drawImage(image, t, observer);
}
+ /**
+ * Draws the specified image at the specified location. The image
+ * is scaled to the specified width and height. This forwards
+ * to {@link #drawImage(Image, AffineTransform, ImageObserver)}.
+ *
+ * @param image the image to render
+ * @param x the x location to render to
+ * @param y the y location to render to
+ * @param width the target width of the image
+ * @param height the target height of the image
+ * @param bgcolor the background color to use for transparent pixels
+ * @param observer the image observer to receive notification
+ */
public boolean drawImage(Image image, int x, int y, int width, int height,
Color bgcolor, ImageObserver observer)
{
- // FIXME: Implement this.
- throw new UnsupportedOperationException("Not yet implemented");
+ AffineTransform t = new AffineTransform();
+ t.translate(x, y);
+ double scaleX = (double) image.getWidth(observer) / (double) width;
+ double scaleY = (double) image.getHeight(observer) / (double) height;
+ t.scale(scaleX, scaleY);
+ // TODO: Somehow implement the background option.
+ return drawImage(image, t, observer);
}
+ /**
+ * Draws an image fragment to a rectangular area of the target.
+ *
+ * @param image the image to render
+ * @param dx1 the first corner of the destination rectangle
+ * @param dy1 the first corner of the destination rectangle
+ * @param dx2 the second corner of the destination rectangle
+ * @param dy2 the second corner of the destination rectangle
+ * @param sx1 the first corner of the source rectangle
+ * @param sy1 the first corner of the source rectangle
+ * @param sx2 the second corner of the source rectangle
+ * @param sy2 the second corner of the source rectangle
+ * @param observer the image observer to be notified
+ */
public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2,
int sx1, int sy1, int sx2, int sy2,
ImageObserver observer)
{
- // FIXME: Implement this.
- throw new UnsupportedOperationException("Not yet implemented");
+ int sx = Math.min(sx1, sx1);
+ int sy = Math.min(sy1, sy2);
+ int sw = Math.abs(sx1 - sx2);
+ int sh = Math.abs(sy1 - sy2);
+ int dx = Math.min(dx1, dx1);
+ int dy = Math.min(dy1, dy2);
+ int dw = Math.abs(dx1 - dx2);
+ int dh = Math.abs(dy1 - dy2);
+
+ AffineTransform t = new AffineTransform();
+ t.translate(sx - dx, sy - dy);
+ double scaleX = (double) sw / (double) dw;
+ double scaleY = (double) sh / (double) dh;
+ t.scale(scaleX, scaleY);
+ Rectangle areaOfInterest = new Rectangle(sx, sy, sw, sh);
+ return drawImageImpl(image, t, observer, areaOfInterest);
}
+ /**
+ * Draws an image fragment to a rectangular area of the target.
+ *
+ * @param image the image to render
+ * @param dx1 the first corner of the destination rectangle
+ * @param dy1 the first corner of the destination rectangle
+ * @param dx2 the second corner of the destination rectangle
+ * @param dy2 the second corner of the destination rectangle
+ * @param sx1 the first corner of the source rectangle
+ * @param sy1 the first corner of the source rectangle
+ * @param sx2 the second corner of the source rectangle
+ * @param sy2 the second corner of the source rectangle
+ * @param bgcolor the background color to use for transparent pixels
+ * @param observer the image observer to be notified
+ */
public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2,
int sx1, int sy1, int sx2, int sy2, Color bgcolor,
ImageObserver observer)
{
- // FIXME: Implement this.
- throw new UnsupportedOperationException("Not yet implemented");
+ // FIXME: Do something with bgcolor.
+ return drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, observer);
}
/**
@@ -1151,8 +1464,8 @@ public abstract class AbstractGraphics2D
Object v = renderingHints.get(RenderingHints.KEY_TEXT_ANTIALIASING);
// We default to antialiasing on for text as long as we have no
// good hinting implemented.
- antialias = (v == RenderingHints.VALUE_TEXT_ANTIALIAS_ON
- || v == RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
+ antialias = (v == RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+ //|| v == RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
}
else
{
@@ -1160,71 +1473,28 @@ public abstract class AbstractGraphics2D
antialias = (v == RenderingHints.VALUE_ANTIALIAS_ON);
}
+ double offs = 0.5;
+ if (antialias)
+ offs = offs / AA_SAMPLING;
+
Rectangle2D userBounds = s.getBounds2D();
Rectangle2D deviceBounds = new Rectangle2D.Double();
- ArrayList segs = getSegments(s, transform, deviceBounds, false);
+ ArrayList segs = getSegments(s, transform, deviceBounds, false, offs);
Rectangle2D clipBounds = new Rectangle2D.Double();
- ArrayList clipSegs = getSegments(clip, transform, clipBounds, true);
+ ArrayList clipSegs = getSegments(clip, transform, clipBounds, true, offs);
segs.addAll(clipSegs);
Rectangle2D inclClipBounds = new Rectangle2D.Double();
Rectangle2D.union(clipBounds, deviceBounds, inclClipBounds);
if (segs.size() > 0)
{
if (antialias)
- fillShapeAntialias(segs, deviceBounds, userBounds);
+ fillShapeAntialias(segs, deviceBounds, userBounds, inclClipBounds);
else
- rawFillShape(segs, deviceBounds, userBounds, inclClipBounds);
+ fillShapeImpl(segs, deviceBounds, userBounds, inclClipBounds);
}
}
/**
- * Draws one pixel in the target coordinate space. This method draws the
- * specified pixel by getting the painting pixel for that coordinate
- * from the paintContext and compositing the pixel with the compositeContext.
- * The resulting pixel is then set by calling {@link #rawSetPixel}.
- *
- * @param x the x coordinate
- * @param y the y coordinate
- */
- protected void drawPixel(int x, int y)
- {
- // FIXME: Implement efficient compositing.
- if (! (paint instanceof Color))
- {
- int[] paintPixel = paintRaster.getPixel(x, y, pixel);
- Color c = new Color(paintPixel[0], paintPixel[1], paintPixel[2]);
- rawSetForeground(c);
- }
- rawSetPixel(x, y);
- }
-
- /**
- * Draws a pixel in the target coordinate space using the specified color.
- *
- * @param x the x coordinate
- * @param y the y coordinate
- */
- protected void rawSetPixel(int x, int y)
- {
- // FIXME: Provide default implementation or remove method.
- }
-
- /**
- * Sets the foreground color for drawing.
- *
- * @param c the color to set
- */
- protected void rawSetForeground(Color c)
- {
- // Probably remove method.
- }
-
- protected void rawSetForeground(int r, int g, int b)
- {
- rawSetForeground(new Color(r, g, b));
- }
-
- /**
* Returns the color model of this Graphics object.
*
* @return the color model of this Graphics object
@@ -1243,7 +1513,8 @@ public abstract class AbstractGraphics2D
/**
* Draws a line in optimization mode. The implementation should respect the
- * clip but can assume that it is a rectangle.
+ * clip and translation. It can assume that the clip is a rectangle and that
+ * the transform is only a translating transform.
*
* @param x0 the starting point, X coordinate
* @param y0 the starting point, Y coordinate
@@ -1252,63 +1523,41 @@ public abstract class AbstractGraphics2D
*/
protected void rawDrawLine(int x0, int y0, int x1, int y1)
{
- // This is an implementation of Bresenham's line drawing algorithm.
- int dy = y1 - y0;
- int dx = x1 - x0;
- int stepx, stepy;
+ draw(new Line2D.Float(x0, y0, x1, y1));
+ }
- if (dy < 0)
- {
- dy = -dy;
- stepy = -1;
- }
- else
- {
- stepy = 1;
- }
- if (dx < 0)
- {
- dx = -dx;
- stepx = -1;
- }
- else
- {
- stepx = 1;
- }
- dy <<= 1;
- dx <<= 1;
+ /**
+ * Draws a string in optimization mode. The implementation should respect the
+ * clip and translation. It can assume that the clip is a rectangle and that
+ * the transform is only a translating transform.
+ *
+ * @param text the string to be drawn
+ * @param x the start of the baseline, X coordinate
+ * @param y the start of the baseline, Y coordinate
+ */
+ protected void rawDrawString(String text, int x, int y)
+ {
+ FontRenderContext ctx = getFontRenderContext();
+ GlyphVector gv = font.createGlyphVector(ctx, text.toCharArray());
+ drawGlyphVector(gv, x, y);
+ }
- drawPixel(x0, y0);
- if (dx > dy)
- {
- int fraction = dy - (dx >> 1); // same as 2*dy - dx
- while (x0 != x1)
- {
- if (fraction >= 0)
- {
- y0 += stepy;
- fraction -= dx;
- }
- x0 += stepx;
- fraction += dy;
- drawPixel(x0, y0);
- }
- }
- else
- {
- int fraction = dx - (dy >> 1);
- while (y0 != y1)
- {
- if (fraction >= 0)
- {
- x0 += stepx;
- fraction -= dy;
- }
- y0 += stepy;
- fraction += dx;
- drawPixel(x0, y0);
- }
- }
+ /**
+ * Clears a rectangle in optimization mode. The implementation should respect the
+ * clip and translation. It can assume that the clip is a rectangle and that
+ * the transform is only a translating transform.
+ *
+ * @param x the upper left corner, X coordinate
+ * @param y the upper left corner, Y coordinate
+ * @param w the width
+ * @param h the height
+ */
+ protected void rawClearRect(int x, int y, int w, int h)
+ {
+ Paint savedForeground = getPaint();
+ setPaint(getBackground());
+ rawFillRect(x, y, w, h);
+ setPaint(savedForeground);
}
/**
@@ -1322,15 +1571,52 @@ public abstract class AbstractGraphics2D
*/
protected void rawFillRect(int x, int y, int w, int h)
{
- int x2 = x + w;
- int y2 = y + h;
- for (int xc = x; xc < x2; xc++)
- {
- for (int yc = y; yc < y2; yc++)
- {
- drawPixel(xc, yc);
- }
- }
+ fill(new Rectangle(x, y, w, h));
+ }
+
+ /**
+ * Draws an image in optimization mode. The implementation should respect
+ * the clip but can assume that it is a rectangle.
+ *
+ * @param image the image to be painted
+ * @param x the location, X coordinate
+ * @param y the location, Y coordinate
+ * @param obs the image observer to be notified
+ *
+ * @return <code>true</code> when the image is painted completely,
+ * <code>false</code> if it is still rendered
+ */
+ protected boolean rawDrawImage(Image image, int x, int y, ImageObserver obs)
+ {
+ AffineTransform t = new AffineTransform();
+ t.translate(x, y);
+ return drawImage(image, t, obs);
+ }
+
+ /**
+ * Copies a rectangular region to another location.
+ *
+ * @param x the upper left corner, X coordinate
+ * @param y the upper left corner, Y coordinate
+ * @param w the width
+ * @param h the height
+ * @param dx
+ * @param dy
+ */
+ protected void rawCopyArea(int x, int y, int w, int h, int dx, int dy)
+ {
+ copyAreaImpl(x, y, w, h, dx, dy);
+ }
+
+ // Private implementation methods.
+
+ /**
+ * Copies a rectangular area of the target raster to a different location.
+ */
+ private void copyAreaImpl(int x, int y, int w, int h, int dx, int dy)
+ {
+ // FIXME: Implement this properly.
+ throw new UnsupportedOperationException("Not implemented yet.");
}
/**
@@ -1340,9 +1626,9 @@ public abstract class AbstractGraphics2D
*
* The polygon is already clipped when this method is called.
*/
- protected void rawFillShape(ArrayList segs, Rectangle2D deviceBounds2D,
- Rectangle2D userBounds,
- Rectangle2D inclClipBounds)
+ private void fillShapeImpl(ArrayList segs, Rectangle2D deviceBounds2D,
+ Rectangle2D userBounds,
+ Rectangle2D inclClipBounds)
{
// This is an implementation of a polygon scanline conversion algorithm
// described here:
@@ -1459,14 +1745,11 @@ public abstract class AbstractGraphics2D
fillScanline(pCtx, x0, x1, y);
}
// Update state.
- if (edge.y1 > y)
- {
- previous = edge;
- if (edge.isClip)
- insideClip = ! insideClip;
- else
- insideShape = ! insideShape;
- }
+ previous = edge;
+ if (edge.isClip)
+ insideClip = ! insideClip;
+ else
+ insideShape = ! insideShape;
}
}
pCtx.dispose();
@@ -1486,7 +1769,8 @@ public abstract class AbstractGraphics2D
CompositeContext cCtx = composite.createContext(paintColorModel,
getColorModel(),
renderingHints);
- cCtx.compose(paintRaster, destinationRaster, destinationRaster);
+ WritableRaster targetChild = destinationRaster.createWritableTranslatedChild(-x0,- y);
+ cCtx.compose(paintRaster, targetChild, targetChild);
updateRaster(destinationRaster, x0, y, x1 - x0, 1);
cCtx.dispose();
}
@@ -1497,7 +1781,8 @@ public abstract class AbstractGraphics2D
* @param segs the line segments which define the shape which is to be filled
*/
private void fillShapeAntialias(ArrayList segs, Rectangle2D deviceBounds2D,
- Rectangle2D userBounds)
+ Rectangle2D userBounds,
+ Rectangle2D inclClipBounds)
{
// This is an implementation of a polygon scanline conversion algorithm
// described here:
@@ -1509,24 +1794,28 @@ public abstract class AbstractGraphics2D
double minY = deviceBounds2D.getMinY();
double maxX = deviceBounds2D.getMaxX();
double maxY = deviceBounds2D.getMaxY();
-
+ double icMinY = inclClipBounds.getMinY();
+ double icMaxY = inclClipBounds.getMaxY();
+ double icMinX = inclClipBounds.getMinX();
+ double icMaxX = inclClipBounds.getMaxX();
Rectangle deviceBounds = new Rectangle((int) minX, (int) minY,
(int) Math.ceil(maxX) - (int) minX,
(int) Math.ceil(maxY) - (int) minY);
- PaintContext pCtx = paint.createContext(getColorModel(), deviceBounds,
+ PaintContext pCtx = paint.createContext(ColorModel.getRGBdefault(),
+ deviceBounds,
userBounds, transform,
renderingHints);
// This array will contain the oversampled transparency values for
// each pixel in the scanline.
- int numScanlines = (int) Math.ceil(maxY) - (int) minY;
- int numScanlinePixels = (int) Math.ceil(maxX) - (int) minX + 1;
+ int numScanlines = (int) Math.ceil(icMaxY) - (int) icMinY;
+ int numScanlinePixels = (int) Math.ceil(icMaxX) - (int) icMinX + 1;
if (alpha == null || alpha.length < (numScanlinePixels + 1))
alpha = new int[numScanlinePixels + 1];
- int firstLine = (int) minY;
+ int firstLine = (int) icMinY;
//System.err.println("minY: " + minY);
- int firstSubline = (int) (Math.ceil((minY - Math.floor(minY)) * AA_SAMPLING));
+ int firstSubline = (int) (Math.ceil((icMinY - Math.floor(icMinY)) * AA_SAMPLING));
double firstLineDouble = firstLine + firstSubline / (double) AA_SAMPLING;
//System.err.println("firstSubline: " + firstSubline);
@@ -1571,8 +1860,11 @@ public abstract class AbstractGraphics2D
// Scan all lines.
int yindex = 0;
//System.err.println("firstLine: " + firstLine + ", maxY: " + maxY + ", firstSubline: " + firstSubline);
- for (int y = firstLine; y <= maxY; y++)
+ for (int y = firstLine; y <= icMaxY; y++)
{
+ int leftX = (int) icMaxX;
+ int rightX = (int) icMinX;
+ boolean emptyScanline = true;
for (int subY = firstSubline; subY < AA_SAMPLING; subY++)
{
//System.err.println("scanline: " + y + ", subScanline: " + subY);
@@ -1629,17 +1921,16 @@ public abstract class AbstractGraphics2D
// Now draw all pixels inside the polygon.
// This is the last edge that intersected the scanline.
PolyEdge previous = null; // Gets initialized below.
- boolean active = false;
+ boolean insideClip = false;
+ boolean insideShape = false;
//System.err.println("scanline: " + y + ", subscanline: " + subY);
for (Iterator i = activeEdges.iterator(); i.hasNext();)
{
PolyEdge edge = (PolyEdge) i.next();
- // Only fill scanline, if the current edge actually intersects
- // the scanline. There may be edges that lie completely
- // within the current scanline.
- //System.err.println("previous: " + previous);
- //System.err.println("edge: " + edge);
- if (active)
+ if (edge.y1 <= (y + (subY / (double) AA_SAMPLING)))
+ continue;
+
+ if (insideClip && insideShape)
{
// TODO: Use integer arithmetics here.
if (edge.y1 > (y + (subY / (double) AA_SAMPLING)))
@@ -1650,32 +1941,30 @@ public abstract class AbstractGraphics2D
int x1 = (int) Math.min(Math.max(edge.xIntersection, minX), maxX);
//System.err.println("minX: " + minX + ", x0: " + x0 + ", x1: " + x1 + ", maxX: " + maxX);
// TODO: Pull out cast.
- alpha[x0 - (int) minX]++;
- alpha[x1 - (int) minX + 1]--;
- previous = edge;
- active = false;
+ int left = x0 - (int) minX;
+ int right = x1 - (int) minX + 1;
+ alpha[left]++;
+ alpha[right]--;
+ leftX = Math.min(x0, leftX);
+ rightX = Math.max(x1+2, rightX);
+ emptyScanline = false;
}
}
+ previous = edge;
+ if (edge.isClip)
+ insideClip = ! insideClip;
else
- {
- // TODO: Use integer arithmetics here.
- if (edge.y1 > (y + (subY / (double) AA_SAMPLING)))
- {
- //System.err.println(edge);
- previous = edge;
- active = true;
- }
- }
+ insideShape = ! insideShape;
}
yindex++;
}
firstSubline = 0;
// Render full scanline.
//System.err.println("scanline: " + y);
- fillScanlineAA(alpha, (int) minX, (int) y, numScanlinePixels, pCtx);
+ if (! emptyScanline)
+ fillScanlineAA(alpha, leftX, (int) y, rightX - leftX, pCtx,
+ (int) minX);
}
- if (paint instanceof Color && composite == AlphaComposite.SrcOver)
- rawSetForeground((Color) paint);
pCtx.dispose();
}
@@ -1689,40 +1978,54 @@ public abstract class AbstractGraphics2D
* @param x0 the beginning of the scanline
* @param y the y coordinate of the line
*/
- private void fillScanlineAA(int[] alpha, int x0, int y, int numScanlinePixels,
- PaintContext pCtx)
+ private void fillScanlineAA(int[] alpha, int x0, int yy, int numPixels,
+ PaintContext pCtx, int offs)
{
- // FIXME: This doesn't work. Fixit.
CompositeContext cCtx = composite.createContext(pCtx.getColorModel(),
getColorModel(),
renderingHints);
- Raster paintRaster = pCtx.getRaster(x0, y, numScanlinePixels, 1);
- System.err.println("paintColorModel: " + pCtx.getColorModel());
+ Raster paintRaster = pCtx.getRaster(x0, yy, numPixels, 1);
+ //System.err.println("paintColorModel: " + pCtx.getColorModel());
WritableRaster aaRaster = paintRaster.createCompatibleWritableRaster();
int numBands = paintRaster.getNumBands();
- int[] pixels = new int[numScanlinePixels + paintRaster.getNumBands()];
- pixels = paintRaster.getPixels(x0, y, numScanlinePixels, 1, pixels);
ColorModel cm = pCtx.getColorModel();
-
double lastAlpha = 0.;
int lastAlphaInt = 0;
- int[] components = new int[4];
-
- for (int i = 0; i < pixels.length; i++)
+
+ Object pixel = null;
+ int[] comps = null;
+ int x1 = x0 + numPixels;
+ for (int x = x0; x < x1; x++)
{
+ int i = x - offs;
if (alpha[i] != 0)
{
lastAlphaInt += alpha[i];
- lastAlpha = lastAlphaInt / AA_SAMPLING;
+ lastAlpha = (double) lastAlphaInt / (double) AA_SAMPLING;
+ alpha[i] = 0;
+ }
+ pixel = paintRaster.getDataElements(x - x0, 0, pixel);
+ comps = cm.getComponents(pixel, comps, 0);
+ if (cm.hasAlpha() && ! cm.isAlphaPremultiplied())
+ comps[comps.length - 1] *= lastAlpha;
+ else
+ {
+ int max;
+ if (cm.hasAlpha())
+ max = comps.length - 2;
+ else
+ max = comps.length - 1;
+ for (int j = 0; j < max; j++)
+ comps[j] *= lastAlpha;
}
- components = cm.getComponents(pixel[i], components, 0);
- components[0] = (int) (components[0] * lastAlpha);
- pixel[i] = cm.getDataElement(components, 0);
+ pixel = cm.getDataElements(comps, 0, pixel);
+ aaRaster.setDataElements(x - x0, 0, pixel);
}
- aaRaster.setPixels(0, 0, numScanlinePixels, 1, pixels);
- cCtx.compose(aaRaster, destinationRaster, destinationRaster);
- updateRaster(destinationRaster, x0, y, numScanlinePixels, 1);
+ WritableRaster targetChild =
+ destinationRaster.createWritableTranslatedChild(-x0, -yy);
+ cCtx.compose(aaRaster, targetChild, targetChild);
+ updateRaster(destinationRaster, x0, yy, numPixels, 1);
cCtx.dispose();
}
@@ -1740,8 +2043,8 @@ public abstract class AbstractGraphics2D
// FIXME: Should not be necessary. A clip of null should mean
// 'clip against device bounds.
- clip = getDeviceBounds();
destinationRaster = getDestinationRaster();
+ clip = getDeviceBounds();
}
/**
@@ -1866,7 +2169,8 @@ public abstract class AbstractGraphics2D
* @return a list of PolyEdge that form the shape in device space
*/
private ArrayList getSegments(Shape s, AffineTransform t,
- Rectangle2D deviceBounds, boolean isClip)
+ Rectangle2D deviceBounds, boolean isClip,
+ double offs)
{
// Flatten the path. TODO: Determine the best flattening factor
// wrt to speed and quality.
@@ -1909,12 +2213,14 @@ public abstract class AbstractGraphics2D
else if (segType == PathIterator.SEG_CLOSE)
{
// Close the polyline.
- PolyEdge edge = new PolyEdge(segX, segY, polyX, polyY, isClip);
+ PolyEdge edge = new PolyEdge(segX, segY - offs,
+ polyX, polyY - offs, isClip);
segs.add(edge);
}
else if (segType == PathIterator.SEG_LINETO)
{
- PolyEdge edge = new PolyEdge(segX, segY, seg[0], seg[1], isClip);
+ PolyEdge edge = new PolyEdge(segX, segY - offs,
+ seg[0], seg[1] - offs, isClip);
segs.add(edge);
segX = seg[0];
segY = seg[1];
diff --git a/gnu/java/awt/java2d/AlphaCompositeContext.java b/gnu/java/awt/java2d/AlphaCompositeContext.java
index e67c92148..2e3690d83 100644
--- a/gnu/java/awt/java2d/AlphaCompositeContext.java
+++ b/gnu/java/awt/java2d/AlphaCompositeContext.java
@@ -236,7 +236,7 @@ public class AlphaCompositeContext
}
else
{
- for (int i = srcComponentsLength - 1; i >= 0; i--)
+ for (int i = srcComponentsLength - 2; i >= 0; i--)
srcComponents[i] *= srcComponents[srcComponentsLength - 1];
}
if (! dstColorModel.isAlphaPremultiplied())
diff --git a/gnu/java/awt/java2d/ImagePaint.java b/gnu/java/awt/java2d/ImagePaint.java
new file mode 100644
index 000000000..7e5fb5638
--- /dev/null
+++ b/gnu/java/awt/java2d/ImagePaint.java
@@ -0,0 +1,192 @@
+/* ImagePaint.java -- Supplies the pixels for image rendering
+ 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.java.awt.java2d;
+
+import java.awt.Paint;
+import java.awt.PaintContext;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.Transparency;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.awt.image.WritableRaster;
+
+/**
+ * This class is used as a temporary Paint object to supply the pixel values
+ * for image rendering using the normal scanline conversion implementation.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+public class ImagePaint
+ implements Paint
+{
+
+ /**
+ * The PaintContext implementation for the ImagePaint.
+ */
+ private class ImagePaintContext
+ implements PaintContext
+ {
+
+ /**
+ * The target raster.
+ */
+ private WritableRaster target;
+
+ /**
+ * Nothing to do here.
+ */
+ public void dispose()
+ {
+ // Nothing to do here.
+ }
+
+ /**
+ * Returns the color model.
+ *
+ * @return the color model
+ */
+ public ColorModel getColorModel()
+ {
+ return image.getColorModel();
+ }
+
+ /**
+ * Supplies the pixel to be rendered.
+ *
+ * @see PaintContext#getRaster(int, int, int, int)
+ */
+ public Raster getRaster(int x1, int y1, int w, int h)
+ {
+ ensureRasterSize(w, h);
+ int x2 = x1 + w;
+ int y2 = y1 + h;
+ float[] src = new float[2];
+ float[] dest = new float[2];
+ Raster source = image.getData();
+ int minX = source.getMinX();
+ int maxX = source.getWidth() + minX;
+ int minY = source.getMinY();
+ int maxY = source.getHeight() + minY;
+ Object pixel = null;
+ for (int y = y1; y < y2; y++)
+ {
+ for (int x = x1; x < x2; x++)
+ {
+ src[0] = x;
+ src[1] = y;
+ transform.transform(src, 0, dest, 0, 1);
+ int dx = (int) dest[0];
+ int dy = (int) dest[1];
+ // Pixels outside the source image are not of interest, skip
+ // them.
+ if (dx >= minX && dx < maxX && dy >= minY && dy < maxY)
+ {
+ pixel = source.getDataElements(dx, dy, pixel);
+ target.setDataElements(x - x1, y - y1, pixel);
+ }
+ }
+ }
+ return target;
+ }
+
+ /**
+ * Ensures that the target raster exists and has at least the specified
+ * size.
+ *
+ * @param w the requested target width
+ * @param h the requested target height
+ */
+ private void ensureRasterSize(int w, int h)
+ {
+ if (target == null || target.getWidth() < w || target.getHeight() < h)
+ {
+ Raster s = image.getData();
+ target = s.createCompatibleWritableRaster(w, h);
+ }
+ }
+ }
+
+ /**
+ * The image to render.
+ */
+ RenderedImage image;
+
+ /**
+ * The transform from image space to device space. This is the inversed
+ * transform of the concatenated
+ * transform image space -> user space -> device space transform.
+ */
+ AffineTransform transform;
+
+ /**
+ * Creates a new ImagePaint for rendering the specified image using the
+ * specified device space -> image space transform. This transform
+ * is the inversed transform of the usual image space -> user space -> device
+ * space transform.
+ *
+ * The ImagePaint will only render the image in the specified area of
+ * interest (which is specified in image space).
+ *
+ * @param i the image to render
+ * @param t the device space to user space transform
+ */
+ ImagePaint(RenderedImage i, AffineTransform t)
+ {
+ image = i;
+ transform = t;
+ }
+
+ public PaintContext createContext(ColorModel cm, Rectangle deviceBounds,
+ Rectangle2D userBounds,
+ AffineTransform xform,
+ RenderingHints hints)
+ {
+ return new ImagePaintContext();
+ }
+
+ public int getTransparency()
+ {
+ return Transparency.OPAQUE;
+ }
+
+}
diff --git a/gnu/java/awt/java2d/RasterGraphics.java b/gnu/java/awt/java2d/RasterGraphics.java
index 4de8035c6..98d47b406 100644
--- a/gnu/java/awt/java2d/RasterGraphics.java
+++ b/gnu/java/awt/java2d/RasterGraphics.java
@@ -65,8 +65,10 @@ public class RasterGraphics
public RasterGraphics(WritableRaster r, ColorModel cm)
{
+ super();
raster = r;
colorModel = cm;
+ init();
}
/**
diff --git a/gnu/java/awt/java2d/TexturePaintContext.java b/gnu/java/awt/java2d/TexturePaintContext.java
new file mode 100644
index 000000000..1a782ce07
--- /dev/null
+++ b/gnu/java/awt/java2d/TexturePaintContext.java
@@ -0,0 +1,205 @@
+/* TexturePaintContext.java -- PaintContext impl for TexturePaint
+ 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.java.awt.java2d;
+
+import java.awt.AWTError;
+import java.awt.PaintContext;
+import java.awt.Rectangle;
+import java.awt.TexturePaint;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+
+/**
+ * A {@link PaintContext} implementation for {@link TexturePaint}, done in
+ * pure Java.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+public class TexturePaintContext
+ implements PaintContext
+{
+
+ /**
+ * The TexturePaint object.
+ */
+ private BufferedImage image;
+
+ /**
+ * The Raster that holds the texture.
+ */
+ private WritableRaster paintRaster;
+
+ /**
+ * The transform from userspace into device space.
+ */
+ private AffineTransform transform;
+
+ /**
+ * Creates a new TexturePaintContext for the specified TexturePaint object.
+ * This initializes the Raster which is returned by
+ * {@link #getRaster(int, int, int, int)}.
+ *
+ * @param t the texture paint object
+ * @param db the bounds of the target raster in device space
+ * @param ub the bounds of the target raster in user space
+ * @param xform the transformation from user space to device space
+ */
+ public TexturePaintContext(TexturePaint t, Rectangle db,
+ Rectangle2D ub, AffineTransform xform)
+ {
+ image = t.getImage();
+
+ try
+ {
+ // Prepare transform for mapping from device space into image space.
+ // In order to achieve this we take the transform for userspace->
+ // devicespace, append the correct scale and translation according
+ // to the anchor (which gives us the image->userspace->devicespace
+ // transform), and invert that (which gives use the device->user->image
+ // transform).
+ Rectangle2D anchor = t.getAnchorRect();
+ BufferedImage image = t.getImage();
+ double scaleX = anchor.getWidth() / image.getWidth();
+ double scaleY = anchor.getHeight() / image.getHeight();
+ transform = (AffineTransform) xform.clone();
+ transform.scale(scaleX, scaleY);
+ transform.translate(-anchor.getMinX(), -anchor.getMaxX());
+ transform = transform.createInverse();
+ }
+ catch (NoninvertibleTransformException ex)
+ {
+ AWTError err =
+ new AWTError("Unexpected NoninvertibleTransformException");
+ err.initCause(ex);
+ throw err;
+ }
+ }
+
+ /**
+ * Disposes the PaintContext. Nothing is to do here, since we don't use
+ * any native resources in that implementation.
+ */
+ public void dispose()
+ {
+ // Nothing to do here.
+ }
+
+ /**
+ * Returns the color model of this PaintContext. This implementation returnes
+ * the color model used by the BufferedImage in the TexturePaint object,
+ * this avoids costly color model transformations (at least at this point).
+ *
+ * @return the color model of this PaintContext
+ */
+ public ColorModel getColorModel()
+ {
+ return image.getColorModel();
+ }
+
+ /**
+ * Returns the Raster that is used for painting.
+ *
+ * @param x1 the x location of the raster inside the user bounds of this paint
+ * context
+ * @param y1 the y location of the raster inside the user bounds of this paint
+ * context
+ * @param w the width
+ * @param h the height
+ *
+ * @return the Raster that is used for painting
+ *
+ */
+ public Raster getRaster(int x1, int y1, int w, int h)
+ {
+ ensureRasterSize(w, h);
+ int x2 = x1 + w;
+ int y2 = y1 + h;
+ float[] src = new float[2];
+ float[] dest = new float[2];
+ Raster source = image.getData();
+ int minX = source.getMinX();
+ int width = source.getWidth();
+ int minY = source.getMinY();
+ int height = source.getHeight();
+ Object pixel = null;
+ for (int y = y1; y < y2; y++)
+ {
+ for (int x = x1; x < x2; x++)
+ {
+ // Transform the coordinates from device space into image space.
+ src[0] = x;
+ src[1] = y;
+ transform.transform(src, 0, dest, 0, 1);
+ int dx = (int) dest[0];
+ int dy = (int) dest[1];
+
+ // The modulo operation gives us the replication effect.
+ dx = ((dx - minX) % width) + minX;
+ dy = ((dy - minY) % height) + minY;
+
+ // Copy the pixel.
+ pixel = source.getDataElements(dx, dy, pixel);
+ paintRaster.setDataElements(x - x1, y - y1, pixel);
+ }
+ }
+ return paintRaster;
+ }
+
+ /**
+ * Ensures that the target raster exists and has at least the specified
+ * size.
+ *
+ * @param w the requested target width
+ * @param h the requested target height
+ */
+ private void ensureRasterSize(int w, int h)
+ {
+ if (paintRaster == null || paintRaster.getWidth() < w
+ || paintRaster.getHeight() < h)
+ {
+ Raster s = image.getData();
+ paintRaster = s.createCompatibleWritableRaster(w, h);
+ }
+ }
+}
diff --git a/gnu/java/awt/peer/gtk/BufferedImageGraphics.java b/gnu/java/awt/peer/gtk/BufferedImageGraphics.java
new file mode 100644
index 000000000..d9d300d91
--- /dev/null
+++ b/gnu/java/awt/peer/gtk/BufferedImageGraphics.java
@@ -0,0 +1,258 @@
+/* BufferedImageGraphics.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.java.awt.peer.gtk;
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.font.GlyphVector;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferInt;
+import java.awt.image.ColorModel;
+import java.awt.image.DirectColorModel;
+import java.awt.image.RenderedImage;
+import java.awt.image.ImageObserver;
+import java.util.WeakHashMap;
+
+/**
+ * Implementation of Graphics2D on a Cairo surface.
+ *
+ * Simutanously maintains a CairoSurface and updates the
+ * BufferedImage from that after each drawing operation.
+ */
+public class BufferedImageGraphics extends CairoGraphics2D
+{
+ /**
+ * the buffered Image.
+ */
+ private BufferedImage image;
+
+ /**
+ * Image size.
+ */
+ private int imageWidth, imageHeight;
+
+ /**
+ * The cairo surface that we actually draw on.
+ */
+ CairoSurface surface;
+
+ /**
+ * Cache BufferedImageGraphics surfaces.
+ */
+ static WeakHashMap bufferedImages = new WeakHashMap();
+
+ /**
+ * Its corresponding cairo_t.
+ */
+ private long cairo_t;
+
+ /**
+ * Colormodels we recognize for fast copying.
+ */
+ static ColorModel rgb32 = new DirectColorModel(32, 0xFF0000, 0xFF00, 0xFF);
+ static ColorModel argb32 = new DirectColorModel(32, 0xFF0000, 0xFF00, 0xFF,
+ 0xFF000000);
+ private boolean hasFastCM;
+ private boolean hasAlpha;
+
+
+ public BufferedImageGraphics(BufferedImage bi)
+ {
+ this.image = bi;
+ imageWidth = bi.getWidth();
+ imageHeight = bi.getHeight();
+ if(bi.getColorModel().equals(rgb32))
+ {
+ hasFastCM = true;
+ hasAlpha = false;
+ }
+ else if(bi.getColorModel().equals(argb32))
+ {
+ hasFastCM = true;
+ hasAlpha = false;
+ }
+ else
+ hasFastCM = false;
+
+ // Cache surfaces.
+ if( bufferedImages.get( bi ) != null )
+ surface = (CairoSurface)bufferedImages.get( bi );
+ else
+ {
+ surface = new CairoSurface( imageWidth, imageHeight );
+ bufferedImages.put(bi, surface);
+ }
+
+ cairo_t = surface.newCairoContext();
+
+ DataBuffer db = bi.getRaster().getDataBuffer();
+ int[] pixels;
+ // get pixels
+
+ if(db instanceof CairoSurface)
+ pixels = ((CairoSurface)db).getPixels(imageWidth * imageHeight);
+ else
+ {
+ if( hasFastCM )
+ {
+ pixels = ((DataBufferInt)db).getData();
+ if( !hasAlpha )
+ for(int i = 0; i < pixels.length; i++)
+ pixels[i] &= 0xFFFFFFFF;
+ }
+ else
+ {
+ pixels = CairoGraphics2D.findSimpleIntegerArray
+ (image.getColorModel(),image.getData());
+ }
+ }
+ surface.setPixels( pixels );
+
+ setup( cairo_t );
+ setClip(0, 0, imageWidth, imageHeight);
+ }
+
+ BufferedImageGraphics(BufferedImageGraphics copyFrom)
+ {
+ surface = copyFrom.surface;
+ cairo_t = surface.newCairoContext();
+ imageWidth = copyFrom.imageWidth;
+ imageHeight = copyFrom.imageHeight;
+ copy( copyFrom, cairo_t );
+ setClip(0, 0, surface.width, surface.height);
+ }
+
+ /**
+ * Update a rectangle of the bufferedImage. This can be improved upon a lot.
+ */
+ private void updateBufferedImage(int x, int y, int width, int height)
+ {
+ int[] pixels = surface.getPixels(imageWidth * imageHeight);
+
+ if( x > imageWidth || y > imageHeight )
+ return;
+ // Clip edges.
+ if( x < 0 ){ width = width + x; x = 0; }
+ if( y < 0 ){ height = height + y; y = 0; }
+ if( x + width > imageWidth )
+ width = imageWidth - x;
+ if( y + height > imageHeight )
+ height = imageHeight - y;
+
+ if( !hasFastCM )
+ image.setRGB(x, y, width, height, pixels,
+ x + y * imageWidth, imageWidth);
+ else
+ System.arraycopy(pixels, y * imageWidth,
+ ((DataBufferInt)image.getRaster().getDataBuffer()).
+ getData(), y * imageWidth, height * imageWidth);
+ }
+
+ /**
+ * Abstract methods.
+ */
+ public Graphics create()
+ {
+ return new BufferedImageGraphics(this);
+ }
+
+ public GraphicsConfiguration getDeviceConfiguration()
+ {
+ return null;
+ }
+
+ protected Rectangle2D getRealBounds()
+ {
+ return new Rectangle2D.Double(0.0, 0.0, imageWidth, imageHeight);
+ }
+
+ public void copyAreaImpl(int x, int y, int width, int height, int dx, int dy)
+ {
+ surface.copyAreaNative(x, y, width, height, dx, dy, surface.width);
+ updateBufferedImage(x + dx, y + dy, width, height);
+ }
+
+ /**
+ * Overloaded methods that do actual drawing need to enter the gdk threads
+ * and also do certain things before and after.
+ */
+ public void draw(Shape s)
+ {
+ super.draw(s);
+ Rectangle r = s.getBounds();
+ updateBufferedImage(r.x, r.y, r.width, r.height);
+ }
+
+ public void fill(Shape s)
+ {
+ super.fill(s);
+ Rectangle r = s.getBounds();
+ updateBufferedImage(r.x, r.y, r.width, r.height);
+ }
+
+ public void drawRenderedImage(RenderedImage image, AffineTransform xform)
+ {
+ super.drawRenderedImage(image, xform);
+ updateBufferedImage(0, 0, imageWidth, imageHeight);
+ }
+
+ protected boolean drawImage(Image img, AffineTransform xform,
+ Color bgcolor, ImageObserver obs)
+ {
+ boolean rv = super.drawImage(img, xform, bgcolor, obs);
+ updateBufferedImage(0, 0, imageWidth, imageHeight);
+ return rv;
+ }
+
+ public void drawGlyphVector(GlyphVector gv, float x, float y)
+ {
+ super.drawGlyphVector(gv, x, y);
+ updateBufferedImage(0, 0, imageWidth, imageHeight);
+ }
+}
+
diff --git a/gnu/java/awt/peer/gtk/GdkGraphics2D.java b/gnu/java/awt/peer/gtk/CairoGraphics2D.java
index 323d5614a..dfebd995b 100644
--- a/gnu/java/awt/peer/gtk/GdkGraphics2D.java
+++ b/gnu/java/awt/peer/gtk/CairoGraphics2D.java
@@ -1,5 +1,5 @@
-/* GdkGraphics2D.java --
- Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+/* CairoGraphics2D.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -58,17 +58,20 @@ import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Stroke;
+import java.awt.Polygon;
import java.awt.TexturePaint;
import java.awt.Toolkit;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
+import java.awt.geom.Line2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
+import java.awt.geom.RoundRectangle2D;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
@@ -92,93 +95,141 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
-public class GdkGraphics2D extends Graphics2D
+/**
+ * This is an abstract implementation of Graphics2D on Cairo.
+ *
+ * It should be subclassed for different Cairo contexts.
+ *
+ * Note for subclassers: Apart from the constructor (see comments below),
+ * The following abstract methods must be implemented:
+ *
+ * Graphics create()
+ * GraphicsConfiguration getDeviceConfiguration()
+ * copyArea(int x, int y, int width, int height, int dx, int dy)
+ *
+ * Also, dispose() must be overloaded to free any native datastructures
+ * used by subclass and in addition call super.dispose() to free the
+ * native cairographics2d structure and cairo_t.
+ *
+ * @author Sven de Marothy
+ */
+public abstract class CairoGraphics2D extends Graphics2D
{
- //////////////////////////////////////
- ////// State Management Methods //////
- //////////////////////////////////////
-
static
{
- if (! Configuration.GTK_CAIRO_ENABLED)
- throw new Error("Graphics2D not implemented. "
- + "Cairo was not found or disabled at configure time");
-
- if (Configuration.INIT_LOAD_LIBRARY)
- System.loadLibrary("gtkpeer");
-
- initStaticState();
+ System.loadLibrary("gtkpeer");
}
-
- static native void initStaticState();
-
- private final int native_state = GtkGenericPeer.getUniqueInteger();
- // These are package-private to avoid accessor methods.
+ /**
+ * Important: This is a pointer to the native cairographics2d structure
+ *
+ * DO NOT CHANGE WITHOUT CHANGING NATIVE CODE.
+ */
+ long nativePointer;
+
+ // Drawing state variables
+ /**
+ * The current paint
+ */
Paint paint;
+
+ /**
+ * The current stroke
+ */
Stroke stroke;
- Color fg;
- Color bg;
+
+ /*
+ * Current foreground and background color.
+ */
+ Color fg, bg;
+
+ /**
+ * Current clip shape.
+ */
Shape clip;
+
+ /**
+ * Current transform.
+ */
AffineTransform transform;
- private GtkComponentPeer component;
- // This is package-private to avoid an accessor method.
+
+ /**
+ * Current font.
+ */
Font font;
- private RenderingHints hints;
- private BufferedImage bimage;
- private boolean pixelConversionRequired;
- private int[] pixelBuffer;
- // This is package-private to avoid an accessor method.
+
+ /**
+ * The current compositing context, if any.
+ */
Composite comp;
- private Stack stateStack;
-
- private native void initStateUnlocked(GtkComponentPeer component);
- private native void initState(GtkComponentPeer component);
- private native void initState(int width, int height);
- private native void initState(int[] pixes, int width, int height);
- private native void copyState(GdkGraphics2D g);
- public native void dispose();
- private native void cairoSurfaceSetFilter(int filter);
- private native void cairoSurfaceSetFilterUnlocked(int filter);
- native void connectSignals(GtkComponentPeer component);
- public void finalize()
- {
- dispose();
- }
+ /**
+ * Rendering hint map.
+ */
+ private RenderingHints hints;
- public Graphics create()
- {
- return new GdkGraphics2D(this);
- }
+ /**
+ * Some operations (drawing rather than filling) require that their
+ * coords be shifted to land on 0.5-pixel boundaries, in order to land on
+ * "middle of pixel" coordinates and light up complete pixels.
+ */
+ private boolean shiftDrawCalls = false;
+
+ /**
+ * Keep track if the first clip to be set, which is restored on setClip(null);
+ */
+ private boolean firstClip = true;
+ private Shape originalClip;
+
+ /**
+ * Stroke used for 3DRects
+ */
+ private static BasicStroke draw3DRectStroke = new BasicStroke();
- public Graphics create(int x, int y, int width, int height)
+ static ColorModel rgb32 = new DirectColorModel(32, 0xFF0000, 0xFF00, 0xFF);
+ static ColorModel argb32 = new DirectColorModel(32, 0xFF0000, 0xFF00, 0xFF,
+ 0xFF000000);
+
+ /**
+ * Constructor does nothing.
+ */
+ public CairoGraphics2D()
{
- return new GdkGraphics2D(this, x, y, width, height);
}
- private void fail_g2d ()
- {
- System.err.println ("Attempted to instantiate GdkGraphics2D"
- + " but Graphics2D not enabled. Try again with"
- + " -Dgnu.java.awt.peer.gtk.Graphics=Graphics2D");
- System.exit (1);
+ /**
+ * Sets up the default values and allocates the native cairographics2d structure
+ * @param cairo_t_pointer, a native pointer to a cairo_t of the context.
+ */
+ public void setup(long cairo_t_pointer)
+ {
+ nativePointer = init(cairo_t_pointer);
+ setRenderingHints(new RenderingHints(getDefaultHints()));
+ font = new Font("SansSerif", Font.PLAIN, 12);
+ setColor(Color.black);
+ setBackground(Color.white);
+ setPaint(Color.black);
+ setStroke(new BasicStroke());
+ setTransform(new AffineTransform());
}
- GdkGraphics2D(GdkGraphics2D g)
+ /**
+ * Same as above, but copies the state of another CairoGraphics2D.
+ */
+ public void copy(CairoGraphics2D g, long cairo_t_pointer)
{
- if (!GtkToolkit.useGraphics2D ())
- fail_g2d ();
-
+ nativePointer = init(cairo_t_pointer);
paint = g.paint;
stroke = g.stroke;
setRenderingHints(g.hints);
+
+ Color foreground;
if (g.fg.getAlpha() != -1)
- fg = new Color(g.fg.getRed(), g.fg.getGreen(), g.fg.getBlue(),
+ foreground = new Color(g.fg.getRed(), g.fg.getGreen(), g.fg.getBlue(),
g.fg.getAlpha());
else
- fg = new Color(g.fg.getRGB());
+ foreground = new Color(g.fg.getRGB());
if (g.bg != null)
{
@@ -200,496 +251,287 @@ public class GdkGraphics2D extends Graphics2D
transform = new AffineTransform(g.transform);
font = g.font;
- component = g.component;
- copyState(g);
- setColor(fg);
+ setColor(foreground);
setBackground(bg);
setPaint(paint);
setStroke(stroke);
setTransform(transform);
- setClip(clip);
- stateStack = new Stack();
}
- GdkGraphics2D(GdkGraphics2D g, int x, int y, int widht, int height)
- {
- this(g);
- translate(x, y);
- clipRect(0, 0, widht, height);
- }
-
- GdkGraphics2D(int width, int height)
- {
- if (!GtkToolkit.useGraphics2D ())
- fail_g2d ();
-
- initState(width, height);
-
- setColor(Color.black);
- setBackground(new Color(0, 0, 0, 0));
- setPaint(getColor());
- setFont(new Font("SansSerif", Font.PLAIN, 12));
- setTransform(new AffineTransform());
- setStroke(new BasicStroke());
- setRenderingHints(getDefaultHints());
-
- stateStack = new Stack();
- }
-
- GdkGraphics2D(GtkComponentPeer component)
+ /**
+ * Generic destructor - call the native dispose() method.
+ */
+ public void finalize()
{
- if (!GtkToolkit.useGraphics2D ())
- fail_g2d ();
-
- this.component = component;
-
- if (component.isRealized())
- initComponentGraphics2D();
- else
- connectSignals(component);
+ dispose();
}
- void initComponentGraphics2D()
- {
- initState(component);
-
- setColor(component.awtComponent.getForeground());
- setBackground(component.awtComponent.getBackground());
- setPaint(getColor());
- setTransform(new AffineTransform());
- setStroke(new BasicStroke());
- setRenderingHints(getDefaultHints());
- setFont(new Font("SansSerif", Font.PLAIN, 12));
-
- stateStack = new Stack();
+ /**
+ * Disposes the native cairographics2d structure, including the
+ * cairo_t and any gradient stuff, if allocated.
+ * Subclasses should of course overload and call this if
+ * they have additional native structures.
+ */
+ public void dispose()
+ {
+ disposeNative();
+ nativePointer = 0;
}
- void initComponentGraphics2DUnlocked()
- {
- initStateUnlocked(component);
-
- setColorUnlocked(component.awtComponent.getForeground());
- setBackgroundUnlocked(component.awtComponent.getBackground());
- setPaintUnlocked(getColorUnlocked());
- setTransformUnlocked(new AffineTransform());
- setStrokeUnlocked(new BasicStroke());
- setRenderingHintsUnlocked(getDefaultHints());
- setFontUnlocked(new Font("SansSerif", Font.PLAIN, 12));
-
- stateStack = new Stack();
- }
+ /**
+ * Allocate the cairographics2d structure and set the cairo_t pointer in it.
+ * @param pointer - a cairo_t pointer, casted to a long.
+ */
+ private native long init(long pointer);
- GdkGraphics2D(BufferedImage bimage)
- {
- this.bimage = bimage;
- this.pixelBuffer = findSimpleIntegerArray(bimage.getColorModel(),
- bimage.getRaster());
- if (this.pixelBuffer == null)
- {
- this.pixelBuffer = new int[bimage.getRaster().getWidth() * bimage.getRaster()
- .getHeight()];
- this.pixelConversionRequired = true;
- }
- else
- {
- this.pixelConversionRequired = false;
- }
+ /**
+ * These are declared abstract as there may be context-specific issues.
+ */
+ public abstract Graphics create();
- initState(this.pixelBuffer, bimage.getWidth(), bimage.getHeight());
+ public abstract GraphicsConfiguration getDeviceConfiguration();
- setColor(Color.black);
- setBackground(new Color(0, 0, 0, 0));
- setPaint(getColor());
- setFont(new Font("SansSerif", Font.PLAIN, 12));
- setTransform(new AffineTransform());
- setStroke(new BasicStroke());
- setRenderingHints(getDefaultHints());
+ protected abstract void copyAreaImpl(int x, int y,
+ int width, int height, int dx, int dy);
- stateStack = new Stack();
- // draw current buffered image to the pixmap associated
- // with it, if the image is not equal to our paint buffer.
- if (pixelConversionRequired)
- drawImage(bimage, new AffineTransform(1, 0, 0, 1, 0, 0), bg, null);
- }
+ protected abstract Rectangle2D getRealBounds();
- ////////////////////////////////////
- ////// Native Drawing Methods //////
- ////////////////////////////////////
+ ////// Native Methods ////////////////////////////////////////////////////
- // GDK drawing methods
- private native void gdkDrawDrawable(GdkGraphics2D other, int x, int y);
+ /**
+ * Dispose of allocate native resouces.
+ */
+ public native void disposeNative();
- // drawing utility methods
+ /**
+ * Draw pixels as an RGBA int matrix
+ * @param w, h - width and height
+ * @param stride - stride of the array width
+ * @param i2u - affine transform array
+ */
private native void drawPixels(int[] pixels, int w, int h, int stride,
double[] i2u);
- private native void setTexturePixelsUnlocked(int[] pixels, int w, int h, int stride);
- private native void setTexturePixels(int[] pixels, int w, int h, int stride);
+
private native void setGradient(double x1, double y1, double x2, double y2,
int r1, int g1, int b1, int a1, int r2,
int g2, int b2, int a2, boolean cyclic);
- private native void setGradientUnlocked(double x1, double y1, double x2, double y2,
- int r1, int g1, int b1, int a1, int r2,
- int g2, int b2, int a2, boolean cyclic);
+
+ private native void setTexturePixels(int[] pixels, int w, int h, int stride);
- // simple passthroughs to cairo
- private native void cairoSave();
- private native void cairoRestore();
+ /**
+ * Set the current transform matrix
+ */
private native void cairoSetMatrix(double[] m);
- private native void cairoSetMatrixUnlocked(double[] m);
+
+ /**
+ * Set the compositing operator
+ */
private native void cairoSetOperator(int cairoOperator);
+
+ /**
+ * Sets the current color in RGBA as a 0.0-1.0 double
+ */
private native void cairoSetRGBAColor(double red, double green,
double blue, double alpha);
- private native void cairoSetRGBAColorUnlocked(double red, double green,
- double blue, double alpha);
- private native void cairoSetFillRule(int cairoFillRule);
- private native void cairoSetLineWidth(double width);
- private native void cairoSetLineWidthUnlocked(double width);
- private native void cairoSetLineCap(int cairoLineCap);
- private native void cairoSetLineCapUnlocked(int cairoLineCap);
- private native void cairoSetLineJoin(int cairoLineJoin);
- private native void cairoSetLineJoinUnlocked(int cairoLineJoin);
- private native void cairoSetDash(double[] dashes, int ndash, double offset);
- private native void cairoSetDashUnlocked(double[] dashes, int ndash, double offset);
- private native void cairoSetMiterLimit(double limit);
- private native void cairoSetMiterLimitUnlocked(double limit);
- private native void cairoNewPath();
- private native void cairoMoveTo(double x, double y);
- private native void cairoLineTo(double x, double y);
- private native void cairoCurveTo(double x1, double y1, double x2, double y2,
- double x3, double y3);
- private native void cairoRelMoveTo(double dx, double dy);
- private native void cairoRelLineTo(double dx, double dy);
- private native void cairoRelCurveTo(double dx1, double dy1, double dx2,
- double dy2, double dx3, double dy3);
- private native void cairoRectangle(double x, double y, double width,
- double height);
- private native void cairoClosePath();
- private native void cairoStroke();
- private native void cairoFill();
- private native void cairoClip();
-
- /////////////////////////////////////////////
- ////// General Drawing Support Methods //////
- /////////////////////////////////////////////
-
- private class DrawState
- {
- private Paint paint;
- private Stroke stroke;
- private Color fg;
- private Color bg;
- private Shape clip;
- private AffineTransform transform;
- private Font font;
- private Composite comp;
-
- DrawState(GdkGraphics2D g)
- {
- this.paint = g.paint;
- this.stroke = g.stroke;
- this.fg = g.fg;
- this.bg = g.bg;
- this.clip = g.clip;
- if (g.transform != null)
- this.transform = (AffineTransform) g.transform.clone();
- this.font = g.font;
- this.comp = g.comp;
- }
-
- public void restore(GdkGraphics2D g)
- {
- g.paint = this.paint;
- g.stroke = this.stroke;
- g.fg = this.fg;
- g.bg = this.bg;
- g.clip = this.clip;
- g.transform = this.transform;
- g.font = this.font;
- g.comp = this.comp;
- }
- }
-
- private void stateSave()
- {
- stateStack.push(new DrawState(this));
- cairoSave();
- }
-
- private void stateRestore()
- {
- ((DrawState) (stateStack.pop())).restore(this);
- cairoRestore();
- }
-
- // Some operations (drawing rather than filling) require that their
- // coords be shifted to land on 0.5-pixel boundaries, in order to land on
- // "middle of pixel" coordinates and light up complete pixels.
- private boolean shiftDrawCalls = false;
-
- private double shifted(double coord, boolean doShift)
- {
- if (doShift)
- return Math.floor(coord) + 0.5;
- else
- return coord;
- }
-
- private void walkPath(PathIterator p, boolean doShift)
- {
- double x = 0;
- double y = 0;
- double[] coords = new double[6];
-
- cairoSetFillRule(p.getWindingRule());
- for (; ! p.isDone(); p.next())
- {
- int seg = p.currentSegment(coords);
- switch (seg)
- {
- case PathIterator.SEG_MOVETO:
- x = shifted(coords[0], doShift);
- y = shifted(coords[1], doShift);
- cairoMoveTo(x, y);
- break;
- case PathIterator.SEG_LINETO:
- x = shifted(coords[0], doShift);
- y = shifted(coords[1], doShift);
- cairoLineTo(x, y);
- break;
- case PathIterator.SEG_QUADTO:
- // splitting a quadratic bezier into a cubic:
- // see: http://pfaedit.sourceforge.net/bezier.html
- double x1 = x + (2.0 / 3.0) * (shifted(coords[0], doShift) - x);
- double y1 = y + (2.0 / 3.0) * (shifted(coords[1], doShift) - y);
-
- double x2 = x1 + (1.0 / 3.0) * (shifted(coords[2], doShift) - x);
- double y2 = y1 + (1.0 / 3.0) * (shifted(coords[3], doShift) - y);
-
- x = shifted(coords[2], doShift);
- y = shifted(coords[3], doShift);
- cairoCurveTo(x1, y1, x2, y2, x, y);
- break;
- case PathIterator.SEG_CUBICTO:
- x = shifted(coords[4], doShift);
- y = shifted(coords[5], doShift);
- cairoCurveTo(shifted(coords[0], doShift),
- shifted(coords[1], doShift),
- shifted(coords[2], doShift),
- shifted(coords[3], doShift), x, y);
- break;
- case PathIterator.SEG_CLOSE:
- cairoClosePath();
- break;
- }
- }
- }
+ /**
+ * Sets the current winding rule in Cairo
+ */
+ private native void cairoSetFillRule(int cairoFillRule);
- private Map getDefaultHints()
- {
- HashMap defaultHints = new HashMap();
+ /**
+ * Set the line style, cap, join and miter limit.
+ * Cap and join parameters are in the BasicStroke enumerations.
+ */
+ private native void cairoSetLine(double width, int cap, int join, double miterLimit);
- defaultHints.put(RenderingHints.KEY_TEXT_ANTIALIASING,
- RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
+ /**
+ * Set the dash style
+ */
+ private native void cairoSetDash(double[] dashes, int ndash, double offset);
- defaultHints.put(RenderingHints.KEY_STROKE_CONTROL,
- RenderingHints.VALUE_STROKE_DEFAULT);
+ /*
+ * Draws a Glyph Vector
+ */
+ native void cairoDrawGlyphVector(GdkFontPeer font,
+ float x, float y, int n,
+ int[] codes, float[] positions);
- defaultHints.put(RenderingHints.KEY_FRACTIONALMETRICS,
- RenderingHints.VALUE_FRACTIONALMETRICS_OFF);
- defaultHints.put(RenderingHints.KEY_ANTIALIASING,
- RenderingHints.VALUE_ANTIALIAS_OFF);
+ private native void cairoRelCurveTo(double dx1, double dy1, double dx2,
+ double dy2, double dx3, double dy3);
- defaultHints.put(RenderingHints.KEY_RENDERING,
- RenderingHints.VALUE_RENDER_DEFAULT);
+ /**
+ * Appends a rectangle to the current path
+ */
+ private native void cairoRectangle(double x, double y, double width,
+ double height);
- return defaultHints;
- }
+ /**
+ * New current path
+ */
+ private native void cairoNewPath();
- public static int[] findSimpleIntegerArray (ColorModel cm, Raster raster)
- {
- if (cm == null || raster == null)
- return null;
+ /**
+ * Close current path
+ */
+ private native void cairoClosePath();
- if (! cm.getColorSpace().isCS_sRGB())
- return null;
+ /** moveTo */
+ private native void cairoMoveTo(double x, double y);
- if (! (cm instanceof DirectColorModel))
- return null;
+ /** relative moveTo */
+ private native void cairoRelMoveTo(double dx, double dy);
- DirectColorModel dcm = (DirectColorModel) cm;
+ /** lineTo */
+ private native void cairoLineTo(double x, double y);
- if (dcm.getRedMask() != 0x00FF0000 || dcm.getGreenMask() != 0x0000FF00
- || dcm.getBlueMask() != 0x000000FF)
- return null;
+ /** relative lineTo */
+ private native void cairoRelLineTo(double dx, double dy);
- if (! (raster instanceof WritableRaster))
- return null;
+ /** Cubic curve-to */
+ private native void cairoCurveTo(double x1, double y1, double x2, double y2,
+ double x3, double y3);
- if (raster.getSampleModel().getDataType() != DataBuffer.TYPE_INT)
- return null;
+ /**
+ * Stroke current path
+ */
+ private native void cairoStroke();
- if (! (raster.getDataBuffer() instanceof DataBufferInt))
- return null;
+ /**
+ * Fill current path
+ */
+ private native void cairoFill();
- DataBufferInt db = (DataBufferInt) raster.getDataBuffer();
+ /**
+ * Clip current path
+ */
+ private native void cairoClip();
- if (db.getNumBanks() != 1)
- return null;
+ /**
+ * Save clip
+ */
+ private native void cairoPreserveClip();
- // Finally, we have determined that this is a single bank, [A]RGB-int
- // buffer in sRGB space. It's worth checking all this, because it means
- // that cairo can paint directly into the data buffer, which is very
- // fast compared to all the normal copying and converting.
+ /**
+ * Save clip
+ */
+ private native void cairoResetClip();
- return db.getData();
- }
+ /**
+ * Set interpolation types
+ */
+ private native void cairoSurfaceSetFilter(int filter);
- private void updateBufferedImage()
+ ///////////////////////// TRANSFORMS ///////////////////////////////////
+ /**
+ * Set the current transform
+ */
+ public void setTransform(AffineTransform tx)
{
- if (bimage != null && pixelConversionRequired)
+ transform = tx;
+ if (transform != null)
{
- int height = bimage.getHeight();
- int width = bimage.getWidth();
- int index = 0;
- for (int y = 0; y < height; ++y)
- for (int x = 0; x < width; ++x)
- bimage.setRGB(x, y, pixelBuffer[index++]);
+ double[] m = new double[6];
+ transform.getMatrix(m);
+ cairoSetMatrix(m);
}
}
-
- private boolean drawImage(Image img, AffineTransform xform,
- Color bgcolor, ImageObserver obs)
+
+ public void transform(AffineTransform tx)
{
- if (img == null)
- return false;
-
- // FIXME: I'll fix this, /Sven
-// if (img instanceof GtkOffScreenImage
-// && img.getGraphics() instanceof GdkGraphics2D
-// && (xform == null || xform.getType() == AffineTransform.TYPE_IDENTITY
-// || xform.getType() == AffineTransform.TYPE_TRANSLATION))
-// {
-// // we are being asked to flush a double buffer from Gdk
-// GdkGraphics2D g2 = (GdkGraphics2D) img.getGraphics();
-// gdkDrawDrawable(g2, (int) xform.getTranslateX(),
-// (int) xform.getTranslateY());
-
-// updateBufferedImage();
-
-// return true;
-// }
-// else
+ if (transform == null)
+ transform = new AffineTransform(tx);
+ else
+ transform.concatenate(tx);
+ setTransform(transform);
+ if (clip != null)
{
- // In this case, xform is an AffineTransform that transforms bounding
- // box of the specified image from image space to user space. However
- // when we pass this transform to cairo, cairo will use this transform
- // to map "user coordinates" to "pixel" coordinates, which is the
- // other way around. Therefore to get the "user -> pixel" transform
- // that cairo wants from "image -> user" transform that we currently
- // have, we will need to invert the transformation matrix.
- AffineTransform invertedXform = new AffineTransform();
-
+ // FIXME: this should actuall try to transform the shape
+ // rather than degrade to bounds.
+ Rectangle2D r = clip.getBounds2D();
+ double[] coords = new double[]
+ {
+ r.getX(), r.getY(), r.getX() + r.getWidth(),
+ r.getY() + r.getHeight()
+ };
try
{
- invertedXform = xform.createInverse();
- if (img instanceof BufferedImage)
- {
- // draw an image which has actually been loaded
- // into memory fully
- BufferedImage b = (BufferedImage) img;
- return drawRaster(b.getColorModel(), b.getTile(0, 0),
- invertedXform, bgcolor);
- }
- else
- return this.drawImage(GdkPixbufDecoder.createBufferedImage(img
- .getSource()),
- xform, bgcolor, obs);
+ tx.createInverse().transform(coords, 0, coords, 0, 2);
+ r.setRect(coords[0], coords[1], coords[2] - coords[0],
+ coords[3] - coords[1]);
+ clip = r;
}
- catch (NoninvertibleTransformException e)
+ catch (java.awt.geom.NoninvertibleTransformException e)
{
- throw new ImagingOpException("Unable to invert transform "
- + xform.toString());
}
}
}
- //////////////////////////////////////////////////
- ////// Implementation of Graphics2D Methods //////
- //////////////////////////////////////////////////
-
- public void draw(Shape s)
+ public void rotate(double theta)
{
- if (stroke != null && ! (stroke instanceof BasicStroke))
- {
- fill(stroke.createStrokedShape(s));
- return;
- }
-
- cairoNewPath();
+ transform(AffineTransform.getRotateInstance(theta));
+ }
- if (s instanceof Rectangle2D)
- {
- Rectangle2D r = (Rectangle2D) s;
- cairoRectangle(shifted(r.getX(), shiftDrawCalls),
- shifted(r.getY(), shiftDrawCalls), r.getWidth(),
- r.getHeight());
- }
- else
- walkPath(s.getPathIterator(null), shiftDrawCalls);
- cairoStroke();
+ public void rotate(double theta, double x, double y)
+ {
+ transform(AffineTransform.getRotateInstance(theta, x, y));
+ }
- updateBufferedImage();
+ public void scale(double sx, double sy)
+ {
+ transform(AffineTransform.getScaleInstance(sx, sy));
}
- public void fill(Shape s)
+ /**
+ * Translate the system of the co-ordinates. As translation is a frequent
+ * operation, it is done in an optimised way, unlike scaling and rotating.
+ */
+ public void translate(double tx, double ty)
{
- cairoNewPath();
- if (s instanceof Rectangle2D)
+ if (transform != null)
+ transform.translate(tx, ty);
+ else
+ transform = AffineTransform.getTranslateInstance(tx, ty);
+
+ if (clip != null)
{
- Rectangle2D r = (Rectangle2D) s;
- cairoRectangle(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+ // FIXME: this should actuall try to transform the shape
+ // rather than degrade to bounds.
+ Rectangle2D r;
+
+ if (clip instanceof Rectangle2D)
+ r = (Rectangle2D) clip;
+ else
+ r = clip.getBounds2D();
+
+ r.setRect(r.getX() - tx, r.getY() - ty, r.getWidth(), r.getHeight());
+ clip = r;
}
- else
- walkPath(s.getPathIterator(null), false);
- cairoFill();
+ setTransform(transform);
+ }
+
+ public void translate(int x, int y)
+ {
+ translate((double) x, (double) y);
+ }
- updateBufferedImage();
+ public void shear(double shearX, double shearY)
+ {
+ transform(AffineTransform.getShearInstance(shearX, shearY));
}
+ ///////////////////////// DRAWING STATE ///////////////////////////////////
+
public void clip(Shape s)
{
- // update it
- if (clip == null || s == null)
- clip = s;
- else if (s instanceof Rectangle2D && clip instanceof Rectangle2D)
- {
- Rectangle2D r = (Rectangle2D) s;
- Rectangle2D curr = (Rectangle2D) clip;
- clip = curr.createIntersection(r);
- }
- else
- throw new UnsupportedOperationException();
+ if( s == null )
+ setClip( originalClip );
- // draw it
- if (clip != null)
- {
- cairoNewPath();
- if (clip instanceof Rectangle2D)
- {
- Rectangle2D r = (Rectangle2D) clip;
- cairoRectangle(r.getX(), r.getY(), r.getWidth(), r.getHeight());
- }
- else
- walkPath(clip.getPathIterator(null), false);
-
- // cairoClosePath ();
- cairoClip();
- }
+ setClip(s);
}
public Paint getPaint()
@@ -721,8 +563,8 @@ public class GdkGraphics2D extends Graphics2D
int width = (int) tp.getAnchorRect().getWidth();
int height = (int) tp.getAnchorRect().getHeight();
- double scaleX = width / (double) img.getWidth();
- double scaleY = width / (double) img.getHeight();
+ double scaleX = (width+1) / (double) img.getWidth();
+ double scaleY = (height+1) / (double) img.getHeight();
AffineTransform at = new AffineTransform(scaleX, 0, 0, scaleY, 0, 0);
AffineTransformOp op = new AffineTransformOp(at, getRenderingHints());
@@ -745,131 +587,6 @@ public class GdkGraphics2D extends Graphics2D
throw new java.lang.UnsupportedOperationException();
}
- public void setPaintUnlocked(Paint p)
- {
- if (paint == null)
- return;
-
- paint = p;
- if (paint instanceof Color)
- {
- setColorUnlocked((Color) paint);
- }
- else if (paint instanceof TexturePaint)
- {
- TexturePaint tp = (TexturePaint) paint;
- BufferedImage img = tp.getImage();
-
- // map the image to the anchor rectangle
- int width = (int) tp.getAnchorRect().getWidth();
- int height = (int) tp.getAnchorRect().getHeight();
-
- double scaleX = width / (double) img.getWidth();
- double scaleY = width / (double) img.getHeight();
-
- AffineTransform at = new AffineTransform(scaleX, 0, 0, scaleY, 0, 0);
- AffineTransformOp op = new AffineTransformOp(at, getRenderingHints());
- BufferedImage texture = op.filter(img, null);
- int[] pixels = texture.getRGB(0, 0, width, height, null, 0, width);
- setTexturePixelsUnlocked(pixels, width, height, width);
- }
- else if (paint instanceof GradientPaint)
- {
- GradientPaint gp = (GradientPaint) paint;
- Point2D p1 = gp.getPoint1();
- Point2D p2 = gp.getPoint2();
- Color c1 = gp.getColor1();
- Color c2 = gp.getColor2();
- setGradientUnlocked(p1.getX(), p1.getY(), p2.getX(), p2.getY(), c1.getRed(),
- c1.getGreen(), c1.getBlue(), c1.getAlpha(), c2.getRed(),
- c2.getGreen(), c2.getBlue(), c2.getAlpha(), gp.isCyclic());
- }
- else
- throw new java.lang.UnsupportedOperationException();
- }
-
- public void setTransform(AffineTransform tx)
- {
- transform = tx;
- if (transform != null)
- {
- double[] m = new double[6];
- transform.getMatrix(m);
- cairoSetMatrix(m);
- }
- }
-
- public void setTransformUnlocked(AffineTransform tx)
- {
- transform = tx;
- if (transform != null)
- {
- double[] m = new double[6];
- transform.getMatrix(m);
- cairoSetMatrixUnlocked(m);
- }
- }
-
- public void transform(AffineTransform tx)
- {
- if (transform == null)
- transform = new AffineTransform(tx);
- else
- transform.concatenate(tx);
- setTransform(transform);
- if (clip != null)
- {
- // FIXME: this should actuall try to transform the shape
- // rather than degrade to bounds.
- Rectangle2D r = clip.getBounds2D();
- double[] coords = new double[]
- {
- r.getX(), r.getY(), r.getX() + r.getWidth(),
- r.getY() + r.getHeight()
- };
- try
- {
- tx.createInverse().transform(coords, 0, coords, 0, 2);
- r.setRect(coords[0], coords[1], coords[2] - coords[0],
- coords[3] - coords[1]);
- clip = r;
- }
- catch (java.awt.geom.NoninvertibleTransformException e)
- {
- }
- }
- }
-
- public void rotate(double theta)
- {
- transform(AffineTransform.getRotateInstance(theta));
- }
-
- public void rotate(double theta, double x, double y)
- {
- transform(AffineTransform.getRotateInstance(theta, x, y));
- }
-
- public void scale(double sx, double sy)
- {
- transform(AffineTransform.getScaleInstance(sx, sy));
- }
-
- public void translate(double tx, double ty)
- {
- transform(AffineTransform.getTranslateInstance(tx, ty));
- }
-
- public void translate(int x, int y)
- {
- translate((double) x, (double) y);
- }
-
- public void shear(double shearX, double shearY)
- {
- transform(AffineTransform.getShearInstance(shearX, shearY));
- }
-
public Stroke getStroke()
{
return stroke;
@@ -881,10 +598,9 @@ public class GdkGraphics2D extends Graphics2D
if (stroke instanceof BasicStroke)
{
BasicStroke bs = (BasicStroke) stroke;
- cairoSetLineCap(bs.getEndCap());
- cairoSetLineWidth(bs.getLineWidth());
- cairoSetLineJoin(bs.getLineJoin());
- cairoSetMiterLimit(bs.getMiterLimit());
+ cairoSetLine(bs.getLineWidth(), bs.getEndCap(),
+ bs.getLineJoin(), bs.getMiterLimit());
+
float[] dashes = bs.getDashArray();
if (dashes != null)
{
@@ -899,42 +615,14 @@ public class GdkGraphics2D extends Graphics2D
}
}
- public void setStrokeUnlocked(Stroke st)
- {
- stroke = st;
- if (stroke instanceof BasicStroke)
- {
- BasicStroke bs = (BasicStroke) stroke;
- cairoSetLineCapUnlocked(bs.getEndCap());
- cairoSetLineWidthUnlocked(bs.getLineWidth());
- cairoSetLineJoinUnlocked(bs.getLineJoin());
- cairoSetMiterLimitUnlocked(bs.getMiterLimit());
- float[] dashes = bs.getDashArray();
- if (dashes != null)
- {
- double[] double_dashes = new double[dashes.length];
- for (int i = 0; i < dashes.length; i++)
- double_dashes[i] = dashes[i];
- cairoSetDashUnlocked(double_dashes, double_dashes.length,
- (double) bs.getDashPhase());
- }
- else
- cairoSetDashUnlocked(new double[0], 0, 0.0);
- }
- }
-
- ////////////////////////////////////////////////
- ////// Implementation of Graphics Methods //////
- ////////////////////////////////////////////////
-
public void setPaintMode()
{
- setComposite(java.awt.AlphaComposite.SrcOver);
+ setComposite(AlphaComposite.SrcOver);
}
public void setXORMode(Color c)
{
- setComposite(new gnu.java.awt.BitwiseXORComposite(c));
+ // FIXME: implement
}
public void setColor(Color c)
@@ -944,18 +632,17 @@ public class GdkGraphics2D extends Graphics2D
fg = c;
paint = c;
- cairoSetRGBAColor(fg.getRed() / 255.0, fg.getGreen() / 255.0,
- fg.getBlue() / 255.0, fg.getAlpha() / 255.0);
+ updateColor();
}
-
- public void setColorUnlocked(Color c)
+
+ /**
+ * Set the current fg value as the cairo color.
+ */
+ void updateColor()
{
- if (c == null)
- c = Color.BLACK;
-
- fg = c;
- paint = c;
- cairoSetRGBAColorUnlocked(fg.getRed() / 255.0, fg.getGreen() / 255.0,
+ if (fg == null)
+ fg = Color.BLACK;
+ cairoSetRGBAColor(fg.getRed() / 255.0, fg.getGreen() / 255.0,
fg.getBlue() / 255.0, fg.getAlpha() / 255.0);
}
@@ -964,11 +651,6 @@ public class GdkGraphics2D extends Graphics2D
return fg;
}
- public Color getColorUnlocked()
- {
- return getColor();
- }
-
public void clipRect(int x, int y, int width, int height)
{
clip(new Rectangle(x, y, width, height));
@@ -1012,81 +694,41 @@ public class GdkGraphics2D extends Graphics2D
public void setClip(int x, int y, int width, int height)
{
- setClip(new Rectangle2D.Double((double) x, (double) y, (double) width,
- (double) height));
+ if( width < 0 || height < 0 )
+ return;
+
+ setClip(new Rectangle2D.Double(x, y, width, height));
}
public void setClip(Shape s)
- {
- clip = s;
- if (clip == null)
+ {
+ // The first time the clip is set, save it as the original clip
+ // to reset to on s == null. We can rely on this being non-null
+ // because the constructor in subclasses is expected to set the
+ // initial clip properly.
+ if( firstClip )
{
- // Reset clipping.
- if (component != null)
- {
- Dimension d = component.awtComponent.getSize();
- setClip(0, 0, d.width, d.height);
- }
+ originalClip = s;
+ firstClip = false;
}
- else
- {
- cairoNewPath();
- if (s instanceof Rectangle2D)
- {
- Rectangle2D r = (Rectangle2D) s;
- cairoRectangle(r.getX(), r.getY(), r.getWidth(), r.getHeight());
- }
- else
- walkPath(s.getPathIterator(null), false);
-
- // cairoClosePath ();
- cairoClip();
- }
- }
-
- private static BasicStroke draw3DRectStroke = new BasicStroke();
-
- public void draw3DRect(int x, int y, int width, int height, boolean raised)
- {
- Stroke tmp = stroke;
- setStroke(draw3DRectStroke);
- super.draw3DRect(x, y, width, height, raised);
- setStroke(tmp);
- updateBufferedImage();
- }
-
- public void fill3DRect(int x, int y, int width, int height, boolean raised)
- {
- Stroke tmp = stroke;
- setStroke(draw3DRectStroke);
- super.fill3DRect(x, y, width, height, raised);
- setStroke(tmp);
- updateBufferedImage();
- }
- public void drawRect(int x, int y, int width, int height)
- {
- draw(new Rectangle(x, y, width, height));
- }
+ if (s == null)
+ clip = originalClip;
+ else
+ clip = s;
- public void fillRect(int x, int y, int width, int height)
- {
- cairoNewPath();
- cairoRectangle(x, y, width, height);
- cairoFill();
- }
+ cairoResetClip();
- public void clearRect(int x, int y, int width, int height)
- {
- if (bg != null)
- cairoSetRGBAColor(bg.getRed() / 255.0, bg.getGreen() / 255.0,
- bg.getBlue() / 255.0, 1.0);
cairoNewPath();
- cairoRectangle(x, y, width, height);
- cairoFill();
- setColor(fg);
-
- updateBufferedImage();
+ if (clip instanceof Rectangle2D)
+ {
+ Rectangle2D r = (Rectangle2D) clip;
+ cairoRectangle(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+ }
+ else
+ walkPath(clip.getPathIterator(null), false);
+
+ cairoClip();
}
public void setBackground(Color c)
@@ -1096,203 +738,232 @@ public class GdkGraphics2D extends Graphics2D
bg = c;
}
- public void setBackgroundUnlocked(Color c)
- {
- setBackground(c);
- }
-
public Color getBackground()
{
return bg;
}
- private void doPolygon(int[] xPoints, int[] yPoints, int nPoints,
- boolean close, boolean fill)
+ /**
+ * Return the current composite.
+ */
+ public Composite getComposite()
{
- if (nPoints < 1)
- return;
- GeneralPath gp = new GeneralPath(PathIterator.WIND_EVEN_ODD);
- gp.moveTo((float) xPoints[0], (float) yPoints[0]);
- for (int i = 1; i < nPoints; i++)
- gp.lineTo((float) xPoints[i], (float) yPoints[i]);
+ if (comp == null)
+ return AlphaComposite.SrcOver;
+ else
+ return comp;
+ }
- if (close)
- gp.closePath();
+ /**
+ * Sets the current composite context.
+ */
+ public void setComposite(Composite comp)
+ {
+ this.comp = comp;
- Shape sh = gp;
- if (fill == false && stroke != null && ! (stroke instanceof BasicStroke))
+ if (comp instanceof AlphaComposite)
{
- sh = stroke.createStrokedShape(gp);
- fill = true;
+ AlphaComposite a = (AlphaComposite) comp;
+ cairoSetOperator(a.getRule());
+ Color c = getColor();
+ setColor(new Color(c.getRed(), c.getGreen(), c.getBlue(),
+ (int) (a.getAlpha() * ((float) c.getAlpha()))));
}
-
- if (fill)
- fill(sh);
else
- draw(sh);
+ {
+ // FIXME: implement general Composite support
+ throw new java.lang.UnsupportedOperationException();
+ }
}
- public void drawLine(int x1, int y1, int x2, int y2)
+ ///////////////////////// DRAWING PRIMITIVES ///////////////////////////////////
+
+ public void draw(Shape s)
{
- int[] xp = new int[2];
- int[] yp = new int[2];
+ if (stroke != null && ! (stroke instanceof BasicStroke))
+ {
+ fill(stroke.createStrokedShape(s));
+ return;
+ }
- xp[0] = x1;
- xp[1] = x2;
- yp[0] = y1;
- yp[1] = y2;
+ cairoNewPath();
- doPolygon(xp, yp, 2, false, false);
+ if (s instanceof Rectangle2D)
+ {
+ Rectangle2D r = (Rectangle2D) s;
+ cairoRectangle(shifted(r.getX(), shiftDrawCalls),
+ shifted(r.getY(), shiftDrawCalls), r.getWidth(),
+ r.getHeight());
+ }
+ else
+ walkPath(s.getPathIterator(null), shiftDrawCalls);
+ cairoStroke();
}
- public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints)
+ public void fill(Shape s)
{
- doPolygon(xPoints, yPoints, nPoints, true, true);
+ cairoNewPath();
+ if (s instanceof Rectangle2D)
+ {
+ Rectangle2D r = (Rectangle2D) s;
+ cairoRectangle(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+ }
+ else
+ walkPath(s.getPathIterator(null), false);
+
+ cairoFill();
}
- public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
+ /**
+ * Note that the rest of the drawing methods go via fill() or draw() for the drawing,
+ * although subclasses may with to overload these methods where context-specific
+ * optimizations are possible (e.g. bitmaps and fillRect(int, int, int, int)
+ */
+
+ public void clearRect(int x, int y, int width, int height)
{
- doPolygon(xPoints, yPoints, nPoints, true, false);
+ if (bg != null)
+ cairoSetRGBAColor(bg.getRed() / 255.0, bg.getGreen() / 255.0,
+ bg.getBlue() / 255.0, 1.0);
+ fillRect(x, y, width, height);
+ updateColor();
}
- public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints)
+ public void draw3DRect(int x, int y, int width, int height, boolean raised)
{
- doPolygon(xPoints, yPoints, nPoints, false, false);
+ Stroke tmp = stroke;
+ setStroke(draw3DRectStroke);
+ super.draw3DRect(x, y, width, height, raised);
+ setStroke(tmp);
}
- private boolean drawRaster(ColorModel cm, Raster r,
- AffineTransform imageToUser, Color bgcolor)
+ public void drawArc(int x, int y, int width, int height, int startAngle,
+ int arcAngle)
{
- if (r == null)
- return false;
-
- SampleModel sm = r.getSampleModel();
- DataBuffer db = r.getDataBuffer();
-
- if (db == null || sm == null)
- return false;
-
- if (cm == null)
- cm = ColorModel.getRGBdefault();
-
- double[] i2u = new double[6];
- if (imageToUser != null)
- imageToUser.getMatrix(i2u);
- else
- {
- i2u[0] = 1;
- i2u[1] = 0;
- i2u[2] = 0;
- i2u[3] = 1;
- i2u[4] = 0;
- i2u[5] = 0;
- }
-
- int[] pixels = findSimpleIntegerArray(cm, r);
-
- if (pixels == null)
- {
- // FIXME: I don't think this code will work correctly with a non-RGB
- // MultiPixelPackedSampleModel. Although this entire method should
- // probably be rewritten to better utilize Cairo's different supported
- // data formats.
- if (sm instanceof MultiPixelPackedSampleModel)
- {
- pixels = r.getPixels(0, 0, r.getWidth(), r.getHeight(), pixels);
- for (int i = 0; i < pixels.length; i++)
- pixels[i] = cm.getRGB(pixels[i]);
- }
- else
- {
- pixels = new int[r.getWidth() * r.getHeight()];
- for (int i = 0; i < pixels.length; i++)
- pixels[i] = cm.getRGB(db.getElem(i));
- }
- }
-
- // Change all transparent pixels in the image to the specified bgcolor,
- // or (if there's no alpha) fill in an alpha channel so that it paints
- // correctly.
- if (cm.hasAlpha())
- {
- if (bgcolor != null && cm.hasAlpha())
- for (int i = 0; i < pixels.length; i++)
- {
- if (cm.getAlpha(pixels[i]) == 0)
- pixels[i] = bgcolor.getRGB();
- }
- }
- else
- for (int i = 0; i < pixels.length; i++)
- pixels[i] |= 0xFF000000;
+ draw(new Arc2D.Double((double) x, (double) y, (double) width,
+ (double) height, (double) startAngle,
+ (double) arcAngle, Arc2D.OPEN));
+ }
- drawPixels(pixels, r.getWidth(), r.getHeight(), r.getWidth(), i2u);
+ public void drawLine(int x1, int y1, int x2, int y2)
+ {
+ draw(new Line2D.Double(x1, y1, x2, y2));
+ }
- updateBufferedImage();
-
- // Cairo seems loosing the current color.
- setColor(fg);
-
- return true;
+ public void drawRect(int x, int y, int width, int height)
+ {
+ draw(new Rectangle(x, y, width, height));
}
- public void drawRenderedImage(RenderedImage image, AffineTransform xform)
+ public void fillArc(int x, int y, int width, int height, int startAngle,
+ int arcAngle)
{
- drawRaster(image.getColorModel(), image.getData(), xform, bg);
+ fill(new Arc2D.Double((double) x, (double) y, (double) width,
+ (double) height, (double) startAngle,
+ (double) arcAngle, Arc2D.OPEN));
}
- public void drawRenderableImage(RenderableImage image, AffineTransform xform)
+ public void fillRect(int x, int y, int width, int height)
{
- drawRenderedImage(image.createRendering(new RenderContext(xform)), xform);
+ fill(new Rectangle(x, y, width, height));
}
- public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs)
+ public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints)
{
- return drawImage(img, xform, bg, obs);
+ fill(new Polygon(xPoints, yPoints, nPoints));
}
- public void drawImage(BufferedImage image, BufferedImageOp op, int x, int y)
+ public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
{
- Image filtered = op.filter(image, null);
- drawImage(filtered, new AffineTransform(1f, 0f, 0f, 1f, x, y), bg, null);
+ draw(new Polygon(xPoints, yPoints, nPoints));
}
- public boolean drawImage(Image img, int x, int y, ImageObserver observer)
+ public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints)
{
- return drawImage(img, new AffineTransform(1f, 0f, 0f, 1f, x, y), bg,
- observer);
+ draw(new Polygon(xPoints, yPoints, nPoints));
}
- ///////////////////////////////////////////////
- ////// Unimplemented Stubs and Overloads //////
- ///////////////////////////////////////////////
+ public void drawOval(int x, int y, int width, int height)
+ {
+ drawArc(x, y, width, height, 0, 360);
+ }
- public boolean hit(Rectangle rect, Shape text, boolean onStroke)
+ public void drawRoundRect(int x, int y, int width, int height, int arcWidth,
+ int arcHeight)
{
- throw new java.lang.UnsupportedOperationException();
+ draw(new RoundRectangle2D.Double(x, y, width, height, arcWidth, arcHeight));
}
- public GraphicsConfiguration getDeviceConfiguration()
+ public void fillOval(int x, int y, int width, int height)
{
- throw new java.lang.UnsupportedOperationException();
+ fillArc(x, y, width, height, 0, 360);
}
- public void setComposite(Composite comp)
+ public void fillRoundRect(int x, int y, int width, int height, int arcWidth,
+ int arcHeight)
{
- this.comp = comp;
+ fill(new RoundRectangle2D.Double(x, y, width, height, arcWidth, arcHeight));
+ }
+
+ /**
+ * CopyArea - performs clipping to the native surface as a convenience
+ * (requires getRealBounds). Then calls copyAreaImpl.
+ */
+ public void copyArea(int ox, int oy, int owidth, int oheight,
+ int odx, int ody)
+ {
+ Point2D pos = transform.transform(new Point2D.Double(ox, oy),
+ (Point2D) null);
+ Point2D dim = transform.transform(new Point2D.Double(ox + owidth,
+ oy + oheight),
+ (Point2D) null);
+ Point2D p2 = transform.transform(new Point2D.Double(ox + odx, oy + ody),
+ (Point2D) null);
+ int x = (int)pos.getX();
+ int y = (int)pos.getY();
+ int width = (int)(dim.getX() - pos.getX());
+ int height = (int)(dim.getY() - pos.getY());
+ int dx = (int)(p2.getX() - pos.getX());
+ int dy = (int)(p2.getY() - pos.getY());
+
+ Rectangle2D r = getRealBounds();
+
+ if( width < 0 || height < 0 )
+ return;
+ // Return if outside the surface
+ if( x + dx > r.getWidth() || y + dy > r.getHeight() )
+ return;
- if (comp instanceof AlphaComposite)
+ if( x + dx + width < r.getX() || y + dy + height < r.getY() )
+ return;
+
+ // Clip edges if necessary
+ if( x + dx < r.getX() ) // left
{
- AlphaComposite a = (AlphaComposite) comp;
- cairoSetOperator(a.getRule());
- Color c = getColor();
- setColor(new Color(c.getRed(), c.getGreen(), c.getBlue(),
- (int) (a.getAlpha() * ((float) c.getAlpha()))));
+ width = x + dx + width;
+ x = (int)r.getX() - dx;
}
- else
- throw new java.lang.UnsupportedOperationException();
+
+ if( y + dy < r.getY() ) // top
+ {
+ height = y + dy + height;
+ y = (int)r.getY() - dy;
+ }
+
+ if( x + dx + width >= r.getWidth() ) // right
+ width = (int)r.getWidth() - dx - x;
+
+ if( y + dy + height >= r.getHeight() ) // bottom
+ height = (int)r.getHeight() - dy - y;
+
+ copyAreaImpl(x, y, width, height, dx, dy);
}
+ ///////////////////////// RENDERING HINTS ///////////////////////////////////
+
+ /**
+ * FIXME- support better
+ */
public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue)
{
hints.put(hintKey, hintValue);
@@ -1317,7 +988,7 @@ public class GdkGraphics2D extends Graphics2D
}
shiftDrawCalls = hints.containsValue(RenderingHints.VALUE_STROKE_NORMALIZE)
- || hints.containsValue(RenderingHints.VALUE_STROKE_DEFAULT);
+ || hints.containsValue(RenderingHints.VALUE_STROKE_DEFAULT);
}
public Object getRenderingHint(RenderingHints.Key hintKey)
@@ -1352,74 +1023,137 @@ public class GdkGraphics2D extends Graphics2D
}
shiftDrawCalls = hints.containsValue(RenderingHints.VALUE_STROKE_NORMALIZE)
- || hints.containsValue(RenderingHints.VALUE_STROKE_DEFAULT);
+ || hints.containsValue(RenderingHints.VALUE_STROKE_DEFAULT);
}
- public void setRenderingHintsUnlocked(Map hints)
+ public void addRenderingHints(Map hints)
{
- this.hints = new RenderingHints(getDefaultHints());
this.hints.add(new RenderingHints(hints));
+ }
- if (hints.containsKey(RenderingHints.KEY_INTERPOLATION))
- {
- if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR))
- cairoSurfaceSetFilterUnlocked(0);
+ public RenderingHints getRenderingHints()
+ {
+ return hints;
+ }
- else if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_BILINEAR))
- cairoSurfaceSetFilterUnlocked(1);
+ ///////////////////////// IMAGE. METHODS ///////////////////////////////////
+
+ protected boolean drawImage(Image img, AffineTransform xform,
+ Color bgcolor, ImageObserver obs)
+ {
+ if (img == null)
+ return false;
+
+ // In this case, xform is an AffineTransform that transforms bounding
+ // box of the specified image from image space to user space. However
+ // when we pass this transform to cairo, cairo will use this transform
+ // to map "user coordinates" to "pixel" coordinates, which is the
+ // other way around. Therefore to get the "user -> pixel" transform
+ // that cairo wants from "image -> user" transform that we currently
+ // have, we will need to invert the transformation matrix.
+ AffineTransform invertedXform = new AffineTransform();
+
+ try
+ {
+ invertedXform = xform.createInverse();
+ }
+ catch (NoninvertibleTransformException e)
+ {
+ throw new ImagingOpException("Unable to invert transform "
+ + xform.toString());
}
- if (hints.containsKey(RenderingHints.KEY_ALPHA_INTERPOLATION))
+ // Unrecognized image - convert to a BufferedImage and come back.
+ if( !(img instanceof BufferedImage) )
+ return this.drawImage(Toolkit.getDefaultToolkit().
+ createImage(img.getSource()),
+ xform, bgcolor, obs);
+
+ BufferedImage b = (BufferedImage) img;
+ DataBuffer db;
+ double[] i2u = new double[6];
+ int width = b.getWidth();
+ int height = b.getHeight();
+
+ // If this BufferedImage has a BufferedImageGraphics object,
+ // use the cached CairoSurface that BIG is drawing onto
+ if( BufferedImageGraphics.bufferedImages.get( b ) != null )
+ db = (DataBuffer)BufferedImageGraphics.bufferedImages.get( b );
+ else
+ db = b.getRaster().getDataBuffer();
+
+ invertedXform.getMatrix(i2u);
+
+ if(db instanceof CairoSurface)
{
- if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED))
- cairoSurfaceSetFilterUnlocked(2);
+ ((CairoSurface)db).drawSurface(this, i2u);
+ return true;
+ }
+
+ if( bgcolor != null )
+ {
+ // Fill a rectangle with the background color
+ // to composite the image onto.
+ Paint oldPaint = paint;
+ AffineTransform oldTransform = transform;
+ setPaint( bgcolor );
+ setTransform( invertedXform );
+ fillRect(0, 0, width, height);
+ setTransform( oldTransform );
+ setPaint( oldPaint );
+ }
- else if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY))
- cairoSurfaceSetFilterUnlocked(3);
+ int[] pixels;
- else if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT))
- cairoSurfaceSetFilterUnlocked(4);
+ // Shortcut for easy color models.
+ if( b.getColorModel().equals(rgb32) )
+ {
+ pixels = ((DataBufferInt)db).getData();
+ for(int i = 0; i < pixels.length; i++)
+ pixels[i] |= 0xFF000000;
+ }
+ else if( b.getColorModel().equals(argb32) )
+ {
+ pixels = ((DataBufferInt)db).getData();
+ }
+ else
+ {
+ pixels = b.getRGB(0, 0, width, height,
+ null, 0, width);
}
- shiftDrawCalls = hints.containsValue(RenderingHints.VALUE_STROKE_NORMALIZE)
- || hints.containsValue(RenderingHints.VALUE_STROKE_DEFAULT);
- }
+ drawPixels(pixels, width, height, width, i2u);
- public void addRenderingHints(Map hints)
- {
- this.hints.add(new RenderingHints(hints));
+ // Cairo seems to lose the current color which must be restored.
+ updateColor();
+ return true;
}
- public RenderingHints getRenderingHints()
+ public void drawRenderedImage(RenderedImage image, AffineTransform xform)
{
- return hints;
+ drawRaster(image.getColorModel(), image.getData(), xform, null);
}
- public Composite getComposite()
+ public void drawRenderableImage(RenderableImage image, AffineTransform xform)
{
- if (comp == null)
- return AlphaComposite.SrcOver;
- else
- return comp;
+ drawRenderedImage(image.createRendering(new RenderContext(xform)), xform);
}
- public FontRenderContext getFontRenderContext()
+ public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs)
{
- return new FontRenderContext(transform, true, true);
+ return drawImage(img, xform, null, obs);
}
- public void copyArea(int x, int y, int width, int height, int dx, int dy)
+ public void drawImage(BufferedImage image, BufferedImageOp op, int x, int y)
{
- GdkGraphics2D g = (GdkGraphics2D) create(x, y, width, height);
- gdkDrawDrawable(g, x + dx, y + dy);
+ Image filtered = op.filter(image, null);
+ drawImage(filtered, new AffineTransform(1f, 0f, 0f, 1f, x, y), null, null);
}
- public void drawArc(int x, int y, int width, int height, int startAngle,
- int arcAngle)
+ public boolean drawImage(Image img, int x, int y, ImageObserver observer)
{
- draw(new Arc2D.Double((double) x, (double) y, (double) width,
- (double) height, (double) startAngle,
- (double) arcAngle, Arc2D.OPEN));
+ return drawImage(img, new AffineTransform(1f, 0f, 0f, 1f, x, y), null,
+ observer);
}
public boolean drawImage(Image img, int x, int y, Color bgcolor,
@@ -1434,6 +1168,8 @@ public class GdkGraphics2D extends Graphics2D
{
double scaleX = width / (double) img.getWidth(observer);
double scaleY = height / (double) img.getHeight(observer);
+ if( scaleX == 0 || scaleY == 0 )
+ return true;
return drawImage(img, new AffineTransform(scaleX, 0f, 0f, scaleY, x, y),
bgcolor, observer);
@@ -1442,7 +1178,7 @@ public class GdkGraphics2D extends Graphics2D
public boolean drawImage(Image img, int x, int y, int width, int height,
ImageObserver observer)
{
- return drawImage(img, x, y, width, height, bg, observer);
+ return drawImage(img, x, y, width, height, null, observer);
}
public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2,
@@ -1452,101 +1188,51 @@ public class GdkGraphics2D extends Graphics2D
if (img == null)
return false;
- Image subImage;
-
int sourceWidth = sx2 - sx1;
int sourceHeight = sy2 - sy1;
int destWidth = dx2 - dx1;
int destHeight = dy2 - dy1;
+ if(destWidth == 0 || destHeight == 0 || sourceWidth == 0 ||
+ sourceHeight == 0)
+ return true;
+
double scaleX = destWidth / (double) sourceWidth;
double scaleY = destHeight / (double) sourceHeight;
- // Get the subimage of the source enclosed in the
- // rectangle specified by sx1, sy1, sx2, sy2
-
- if (img instanceof BufferedImage)
- {
- BufferedImage b = (BufferedImage) img;
- subImage = b.getSubimage(sx1, sy1, sx2, sy2);
- }
+ // FIXME: Avoid using an AT if possible here - it's at least twice as slow.
+
+ Shape oldClip = getClip();
+ int cx, cy, cw, ch;
+ if( dx1 < dx2 )
+ { cx = dx1; cw = dx2 - dx1; }
else
- {
- // FIXME: This code currently doesn't work. Null Pointer
- // exception is thrown in this case. This happens
- // because img.getSource() always returns null, since source gets
- // never initialized when it is created with the help of
- // createImage(int width, int height).
- CropImageFilter filter = new CropImageFilter(sx1, sx2, sx2, sy2);
- FilteredImageSource src = new FilteredImageSource(img.getSource(),
- filter);
-
- subImage = Toolkit.getDefaultToolkit().createImage(src);
- }
+ { cx = dx2; cw = dx1 - dx2; }
+ if( dy1 < dy2 )
+ { cy = dy1; ch = dy2 - dy1; }
+ else
+ { cy = dy2; ch = dy1 - dy2; }
+
+ setClip( cx, cy, cw, ch );
- return drawImage(subImage,
- new AffineTransform(scaleX, 0, 0, scaleY, dx1, dy1),
- bgcolor, observer);
+ AffineTransform tx = new AffineTransform();
+ tx.translate( dx1 - sx1*scaleX, dy1 - sy1*scaleY );
+ tx.scale( scaleX, scaleY );
+
+ boolean retval = drawImage(img, tx, bgcolor, observer);
+ setClip( oldClip );
+ return retval;
}
public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2,
int sx1, int sy1, int sx2, int sy2,
ImageObserver observer)
{
- return drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, bg, observer);
- }
-
- public void drawOval(int x, int y, int width, int height)
- {
- drawArc(x, y, width, height, 0, 360);
+ return drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null, observer);
}
- public void drawRoundRect(int x, int y, int width, int height, int arcWidth,
- int arcHeight)
- {
- if (arcWidth > width)
- arcWidth = width;
- if (arcHeight > height)
- arcHeight = height;
-
- int xx = x + width - arcWidth;
- int yy = y + height - arcHeight;
-
- drawArc(x, y, arcWidth, arcHeight, 90, 90);
- drawArc(xx, y, arcWidth, arcHeight, 0, 90);
- drawArc(xx, yy, arcWidth, arcHeight, 270, 90);
- drawArc(x, yy, arcWidth, arcHeight, 180, 90);
-
- int y1 = y + arcHeight / 2;
- int y2 = y + height - arcHeight / 2;
- drawLine(x, y1, x, y2);
- drawLine(x + width, y1, x + width, y2);
-
- int x1 = x + arcWidth / 2;
- int x2 = x + width - arcWidth / 2;
- drawLine(x1, y, x2, y);
- drawLine(x1, y + height, x2, y + height);
- }
-
- // these are the most accelerated painting paths
- native void cairoDrawGlyphVector(GdkFontPeer font,
- float x, float y, int n,
- int[] codes, float[] positions);
-
- native void cairoDrawGdkTextLayout(GdkTextLayout gl,
- float x, float y);
-
- GdkFontPeer getFontPeer()
- {
- return (GdkFontPeer) getFont().getPeer();
- }
-
- public void drawGdkTextLayout(GdkTextLayout gl, float x, float y)
- {
- cairoDrawGdkTextLayout (gl, x, y);
- updateBufferedImage ();
- }
+ ///////////////////////// TEXT METHODS ////////////////////////////////////
public void drawString(String str, float x, float y)
{
@@ -1554,7 +1240,6 @@ public class GdkGraphics2D extends Graphics2D
return;
drawGlyphVector(getFont().createGlyphVector(null, str), x, y);
- updateBufferedImage ();
}
public void drawString(String str, int x, int y)
@@ -1574,8 +1259,7 @@ public class GdkGraphics2D extends Graphics2D
float[] positions = gv.getGlyphPositions (0, n, null);
setFont (gv.getFont ());
- cairoDrawGlyphVector (getFontPeer(), x, y, n, codes, positions);
- updateBufferedImage ();
+ cairoDrawGlyphVector( (GdkFontPeer)getFont().getPeer(), x, y, n, codes, positions);
}
public void drawString(AttributedCharacterIterator ci, float x, float y)
@@ -1584,52 +1268,19 @@ public class GdkGraphics2D extends Graphics2D
drawGlyphVector(gv, x, y);
}
- public void fillArc(int x, int y, int width, int height, int startAngle,
- int arcAngle)
- {
- fill(new Arc2D.Double((double) x, (double) y, (double) width,
- (double) height, (double) startAngle,
- (double) arcAngle, Arc2D.OPEN));
- }
-
- public void fillOval(int x, int y, int width, int height)
- {
- fillArc(x, y, width, height, 0, 360);
- }
-
- public void fillRoundRect(int x, int y, int width, int height, int arcWidth,
- int arcHeight)
- {
- if (arcWidth > width)
- arcWidth = width;
- if (arcHeight > height)
- arcHeight = height;
-
- int xx = x + width - arcWidth;
- int yy = y + height - arcHeight;
-
- fillArc(x, y, arcWidth, arcHeight, 90, 90);
- fillArc(xx, y, arcWidth, arcHeight, 0, 90);
- fillArc(xx, yy, arcWidth, arcHeight, 270, 90);
- fillArc(x, yy, arcWidth, arcHeight, 180, 90);
-
- fillRect(x, y + arcHeight / 2, width, height - arcHeight + 1);
- fillRect(x + arcWidth / 2, y, width - arcWidth + 1, height);
- }
-
- public Font getFont()
+ /**
+ * Should perhaps be contexct dependent, but this is left for now as an
+ * overloadable default implementation.
+ */
+ public FontRenderContext getFontRenderContext()
{
- if (font == null)
- return new Font("SansSerif", Font.PLAIN, 12);
- return font;
+ return new FontRenderContext(transform, true, true);
}
// Until such time as pango is happy to talk directly to cairo, we
// actually need to redirect some calls from the GtkFontPeer and
// GtkFontMetrics into the drawing kit and ask cairo ourselves.
- static native void releasePeerGraphicsResource(GdkFontPeer f);
-
public FontMetrics getFontMetrics()
{
return getFontMetrics(getFont());
@@ -1657,9 +1308,25 @@ public class GdkGraphics2D extends Graphics2D
.getFont(f.getName(), f.getAttributes());
}
- public void setFontUnlocked(Font f)
+ public Font getFont()
{
- setFont (f);
+ if (font == null)
+ return new Font("SansSerif", Font.PLAIN, 12);
+ return font;
+ }
+
+ /////////////////////// MISC. PUBLIC METHODS /////////////////////////////////
+
+ public boolean hit(Rectangle rect, Shape s, boolean onStroke)
+ {
+ if( onStroke )
+ {
+ Shape stroked = stroke.createStrokedShape( s );
+ return stroked.intersects( (double)rect.x, (double)rect.y,
+ (double)rect.width, (double)rect.height );
+ }
+ return s.intersects( (double)rect.x, (double)rect.y,
+ (double)rect.width, (double)rect.height );
}
public String toString()
@@ -1669,4 +1336,218 @@ public class GdkGraphics2D extends Graphics2D
+ ",color=" + fg.toString()
+ "]");
}
+
+ ///////////////////////// PRIVATE METHODS ///////////////////////////////////
+
+ /**
+ * All the drawImage() methods eventually get delegated here if the image
+ * is not a Cairo surface.
+ *
+ * @param bgcolor - if non-null draws the background color before
+ * drawing the image.
+ */
+ private boolean drawRaster(ColorModel cm, Raster r,
+ AffineTransform imageToUser, Color bgcolor)
+ {
+ if (r == null)
+ return false;
+
+ SampleModel sm = r.getSampleModel();
+ DataBuffer db = r.getDataBuffer();
+
+ if (db == null || sm == null)
+ return false;
+
+ if (cm == null)
+ cm = ColorModel.getRGBdefault();
+
+ double[] i2u = new double[6];
+ if (imageToUser != null)
+ imageToUser.getMatrix(i2u);
+ else
+ {
+ i2u[0] = 1;
+ i2u[1] = 0;
+ i2u[2] = 0;
+ i2u[3] = 1;
+ i2u[4] = 0;
+ i2u[5] = 0;
+ }
+
+ int[] pixels = findSimpleIntegerArray(cm, r);
+
+ if (pixels == null)
+ {
+ // FIXME: I don't think this code will work correctly with a non-RGB
+ // MultiPixelPackedSampleModel. Although this entire method should
+ // probably be rewritten to better utilize Cairo's different supported
+ // data formats.
+ if (sm instanceof MultiPixelPackedSampleModel)
+ {
+ pixels = r.getPixels(0, 0, r.getWidth(), r.getHeight(), pixels);
+ for (int i = 0; i < pixels.length; i++)
+ pixels[i] = cm.getRGB(pixels[i]);
+ }
+ else
+ {
+ pixels = new int[r.getWidth() * r.getHeight()];
+ for (int i = 0; i < pixels.length; i++)
+ pixels[i] = cm.getRGB(db.getElem(i));
+ }
+ }
+
+ // Change all transparent pixels in the image to the specified bgcolor,
+ // or (if there's no alpha) fill in an alpha channel so that it paints
+ // correctly.
+ if (cm.hasAlpha())
+ {
+ if (bgcolor != null && cm.hasAlpha())
+ for (int i = 0; i < pixels.length; i++)
+ {
+ if (cm.getAlpha(pixels[i]) == 0)
+ pixels[i] = bgcolor.getRGB();
+ }
+ }
+ else
+ for (int i = 0; i < pixels.length; i++)
+ pixels[i] |= 0xFF000000;
+
+ drawPixels(pixels, r.getWidth(), r.getHeight(), r.getWidth(), i2u);
+
+ // Cairo seems to lose the current color which must be restored.
+ updateColor();
+
+ return true;
+ }
+
+ /**
+ * Shifts coordinates by 0.5.
+ */
+ private double shifted(double coord, boolean doShift)
+ {
+ if (doShift)
+ return Math.floor(coord) + 0.5;
+ else
+ return coord;
+ }
+
+ /**
+ * Adds a pathIterator to the current Cairo path, also sets the cairo winding rule.
+ */
+ private void walkPath(PathIterator p, boolean doShift)
+ {
+ double x = 0;
+ double y = 0;
+ double[] coords = new double[6];
+
+ cairoSetFillRule(p.getWindingRule());
+ for (; ! p.isDone(); p.next())
+ {
+ int seg = p.currentSegment(coords);
+ switch (seg)
+ {
+ case PathIterator.SEG_MOVETO:
+ x = shifted(coords[0], doShift);
+ y = shifted(coords[1], doShift);
+ cairoMoveTo(x, y);
+ break;
+ case PathIterator.SEG_LINETO:
+ x = shifted(coords[0], doShift);
+ y = shifted(coords[1], doShift);
+ cairoLineTo(x, y);
+ break;
+ case PathIterator.SEG_QUADTO:
+ // splitting a quadratic bezier into a cubic:
+ // see: http://pfaedit.sourceforge.net/bezier.html
+ double x1 = x + (2.0 / 3.0) * (shifted(coords[0], doShift) - x);
+ double y1 = y + (2.0 / 3.0) * (shifted(coords[1], doShift) - y);
+
+ double x2 = x1 + (1.0 / 3.0) * (shifted(coords[2], doShift) - x);
+ double y2 = y1 + (1.0 / 3.0) * (shifted(coords[3], doShift) - y);
+
+ x = shifted(coords[2], doShift);
+ y = shifted(coords[3], doShift);
+ cairoCurveTo(x1, y1, x2, y2, x, y);
+ break;
+ case PathIterator.SEG_CUBICTO:
+ x = shifted(coords[4], doShift);
+ y = shifted(coords[5], doShift);
+ cairoCurveTo(shifted(coords[0], doShift),
+ shifted(coords[1], doShift),
+ shifted(coords[2], doShift),
+ shifted(coords[3], doShift), x, y);
+ break;
+ case PathIterator.SEG_CLOSE:
+ cairoClosePath();
+ break;
+ }
+ }
+ }
+
+ /**
+ * Used by setRenderingHints()
+ */
+ private Map getDefaultHints()
+ {
+ HashMap defaultHints = new HashMap();
+
+ defaultHints.put(RenderingHints.KEY_TEXT_ANTIALIASING,
+ RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
+
+ defaultHints.put(RenderingHints.KEY_STROKE_CONTROL,
+ RenderingHints.VALUE_STROKE_DEFAULT);
+
+ defaultHints.put(RenderingHints.KEY_FRACTIONALMETRICS,
+ RenderingHints.VALUE_FRACTIONALMETRICS_OFF);
+
+ defaultHints.put(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_OFF);
+
+ defaultHints.put(RenderingHints.KEY_RENDERING,
+ RenderingHints.VALUE_RENDER_DEFAULT);
+
+ return defaultHints;
+ }
+
+ /**
+ * Used by drawRaster and GdkPixbufDecoder
+ */
+ public static int[] findSimpleIntegerArray (ColorModel cm, Raster raster)
+ {
+ if (cm == null || raster == null)
+ return null;
+
+ if (! cm.getColorSpace().isCS_sRGB())
+ return null;
+
+ if (! (cm instanceof DirectColorModel))
+ return null;
+
+ DirectColorModel dcm = (DirectColorModel) cm;
+
+ if (dcm.getRedMask() != 0x00FF0000 || dcm.getGreenMask() != 0x0000FF00
+ || dcm.getBlueMask() != 0x000000FF)
+ return null;
+
+ if (! (raster instanceof WritableRaster))
+ return null;
+
+ if (raster.getSampleModel().getDataType() != DataBuffer.TYPE_INT)
+ return null;
+
+ if (! (raster.getDataBuffer() instanceof DataBufferInt))
+ return null;
+
+ DataBufferInt db = (DataBufferInt) raster.getDataBuffer();
+
+ if (db.getNumBanks() != 1)
+ return null;
+
+ // Finally, we have determined that this is a single bank, [A]RGB-int
+ // buffer in sRGB space. It's worth checking all this, because it means
+ // that cairo can paint directly into the data buffer, which is very
+ // fast compared to all the normal copying and converting.
+
+ return db.getData();
+ }
}
diff --git a/gnu/java/awt/peer/gtk/CairoSurface.java b/gnu/java/awt/peer/gtk/CairoSurface.java
new file mode 100644
index 000000000..c3b07d874
--- /dev/null
+++ b/gnu/java/awt/peer/gtk/CairoSurface.java
@@ -0,0 +1,280 @@
+/* CairoSurface.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.java.awt.peer.gtk;
+
+import java.awt.Graphics;
+import java.awt.Color;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.image.DataBuffer;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.DirectColorModel;
+import java.io.File;
+import java.io.IOException;
+import java.util.Hashtable;
+import java.util.Vector;
+import java.io.ByteArrayOutputStream;
+import java.io.BufferedInputStream;
+import java.net.URL;
+import gnu.classpath.Pointer;
+
+/**
+ * CairoSurface - wraps a Cairo surface.
+ *
+ * @author Sven de Marothy
+ */
+public class CairoSurface extends DataBuffer
+{
+ int width = -1, height = -1;
+
+ /**
+ * The native pointer to the Cairo surface.
+ */
+ long surfacePointer;
+
+ /**
+ * The native pointer to the image's data buffer
+ */
+ long bufferPointer;
+
+
+ static ColorModel nativeModel = new DirectColorModel(32,
+ 0x000000FF,
+ 0x0000FF00,
+ 0x00FF0000,
+ 0xFF000000);
+
+ /**
+ * Allocates and clears the buffer and creates the cairo surface.
+ * @param width, height - the image size
+ * @param stride - the buffer row stride.
+ */
+ private native void create(int width, int height, int stride);
+
+ /**
+ * Destroys the cairo surface and frees the buffer.
+ */
+ private native void destroy();
+
+ /**
+ * Gets buffer elements
+ */
+ private native int nativeGetElem(int i);
+
+ /**
+ * Sets buffer elements.
+ */
+ private native void nativeSetElem(int i, int val);
+
+ /**
+ * Draws this image to a given CairoGraphics context,
+ * with an affine transform given by i2u.
+ */
+ public native void drawSurface(CairoGraphics2D context, double[] i2u);
+
+ /**
+ * getPixels -return the pixels as a java array.
+ */
+ native int[] getPixels(int size);
+
+ /**
+ * getPixels -return the pixels as a java array.
+ */
+ native void setPixels(int[] pixels);
+
+ native long getFlippedBuffer(int size);
+
+ /**
+ * Create a cairo_surface_t with specified width and height.
+ * The format will be ARGB32 with premultiplied alpha and native bit
+ * and word ordering.
+ */
+ CairoSurface(int width, int height)
+ {
+ super(DataBuffer.TYPE_INT, width * height);
+
+ if(width <= 0 || height <= 0)
+ throw new IllegalArgumentException("Image must be at least 1x1 pixels.");
+
+ this.width = width;
+ this.height = height;
+
+ create(width, height, width * 4);
+
+ if(surfacePointer == 0 || bufferPointer == 0)
+ throw new Error("Could not allocate bitmap.");
+ }
+
+ /**
+ * Create a cairo_surface_t from a GtkImage instance.
+ * (data is copied, not shared)
+ */
+ CairoSurface(GtkImage image)
+ {
+ super(DataBuffer.TYPE_INT, image.width * image.height);
+
+ if(image.width <= 0 || image.height <= 0)
+ throw new IllegalArgumentException("Image must be at least 1x1 pixels.");
+
+ width = image.width;
+ height = image.height;
+
+ create(width, height, width * 4);
+
+ if(surfacePointer == 0 || bufferPointer == 0)
+ throw new Error("Could not allocate bitmap.");
+
+ // Copy the pixel data from the GtkImage.
+ int[] data = image.getPixels();
+
+ // Swap ordering from GdkPixbuf to Cairo
+ for(int i = 0; i < data.length; i++ )
+ {
+ int alpha = (data[i] & 0xFF000000) >> 24;
+ if( alpha == 0 ) // I do not know why we need this, but it works.
+ data[i] = 0;
+ else
+ {
+ int r = (((data[i] & 0x00FF0000) >> 16) );
+ int g = (((data[i] & 0x0000FF00) >> 8) );
+ int b = ((data[i] & 0x000000FF) );
+ data[i] = (( alpha << 24 ) & 0xFF000000)
+ | (( b << 16 ) & 0x00FF0000)
+ | (( g << 8 ) & 0x0000FF00)
+ | ( r & 0x000000FF);
+ }
+ }
+
+ setPixels( data );
+ }
+
+ /**
+ * Dispose of the native data.
+ */
+ public void dispose()
+ {
+ if(surfacePointer != 0)
+ destroy();
+ }
+
+ /**
+ * Return a GtkImage from this Cairo surface.
+ */
+ public GtkImage getGtkImage()
+ {
+ return new GtkImage( width, height, getFlippedBuffer( width * height ));
+ }
+
+ /**
+ * Returns a BufferedImage backed by a Cairo surface.
+ */
+ public static BufferedImage getBufferedImage(int width, int height)
+ {
+ return getBufferedImage(new CairoSurface(width, height));
+ }
+
+ /**
+ * Returns a BufferedImage backed by a Cairo surface,
+ * created from a GtkImage.
+ */
+ public static BufferedImage getBufferedImage(GtkImage image)
+ {
+ return getBufferedImage(new CairoSurface(image));
+ }
+
+ /**
+ * Returns a BufferedImage backed by a Cairo surface.
+ */
+ public static BufferedImage getBufferedImage(CairoSurface surface)
+ {
+ WritableRaster raster = Raster.createPackedRaster
+ (surface, surface.width, surface.height, surface.width,
+ new int[]{ 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 },
+ new Point(0,0));
+
+ return new BufferedImage(nativeModel, raster, true, new Hashtable());
+ }
+
+ /**
+ * DataBank.getElem implementation
+ */
+ public int getElem(int bank, int i)
+ {
+ if(bank != 0 || i < 0 || i >= width*height)
+ throw new IndexOutOfBoundsException(i+" size: "+width*height);
+ return nativeGetElem(i);
+ }
+
+ /**
+ * DataBank.setElem implementation
+ */
+ public void setElem(int bank, int i, int val)
+ {
+ if(bank != 0 || i < 0 || i >= width*height)
+ throw new IndexOutOfBoundsException(i+" size: "+width*height);
+ nativeSetElem(i, val);
+ }
+
+ /**
+ * Return a Graphics2D drawing to the CairoSurface.
+ */
+ public Graphics2D getGraphics()
+ {
+ return new CairoSurfaceGraphics(this);
+ }
+
+ ///// Methods used by CairoSurfaceGraphics /////
+ /**
+ * Creates a cairo_t drawing context, returns the pointer as a long.
+ * Used by CairoSurfaceGraphics.
+ */
+ native long newCairoContext();
+
+ /**
+ * Copy an area of the surface. Expects parameters must be within bounds.
+ * Count on a segfault otherwise.
+ */
+ native void copyAreaNative(int x, int y, int width, int height,
+ int dx, int dy, int stride);
+}
diff --git a/gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java b/gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java
new file mode 100644
index 000000000..38c549d1d
--- /dev/null
+++ b/gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java
@@ -0,0 +1,100 @@
+/* CairoSurfaceGraphics.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.java.awt.peer.gtk;
+
+import java.awt.Graphics;
+import java.awt.Color;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.*;
+
+/**
+ * Implementation of Graphics2D on a Cairo surface.
+ */
+public class CairoSurfaceGraphics extends CairoGraphics2D
+{
+ protected CairoSurface surface;
+ private long cairo_t;
+
+ /**
+ * Create a graphics context from a cairo surface
+ */
+ public CairoSurfaceGraphics(CairoSurface surface)
+ {
+ this.surface = surface;
+ cairo_t = surface.newCairoContext();
+ setup( cairo_t );
+ setClip(0, 0, surface.width, surface.height);
+ }
+
+ /**
+ * Creates another context from a surface.
+ * Used by create().
+ */
+ private CairoSurfaceGraphics(CairoSurfaceGraphics copyFrom)
+ {
+ surface = copyFrom.surface;
+ cairo_t = surface.newCairoContext();
+ copy( copyFrom, cairo_t );
+ setClip(0, 0, surface.width, surface.height);
+ }
+
+ public Graphics create()
+ {
+ return new CairoSurfaceGraphics(this);
+ }
+
+ public GraphicsConfiguration getDeviceConfiguration()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ protected Rectangle2D getRealBounds()
+ {
+ return new Rectangle2D.Double(0.0, 0.0, surface.width, surface.height);
+ }
+
+ public void copyAreaImpl(int x, int y, int width, int height, int dx, int dy)
+ {
+ surface.copyAreaNative(x, y, width, height, dx, dy, surface.width);
+ }
+}
diff --git a/gnu/java/awt/peer/gtk/ComponentGraphics.java b/gnu/java/awt/peer/gtk/ComponentGraphics.java
new file mode 100644
index 000000000..5f17d7bef
--- /dev/null
+++ b/gnu/java/awt/peer/gtk/ComponentGraphics.java
@@ -0,0 +1,220 @@
+/* ComponentGraphics.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.java.awt.peer.gtk;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.Image;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImagingOpException;
+import java.awt.image.RenderedImage;
+
+/**
+ * ComponentGraphics - context for drawing directly to a component,
+ * as this is an X drawable, it requires that we use GTK locks.
+ *
+ * This context draws directly to the drawable and requires xrender.
+ */
+public class ComponentGraphics extends CairoGraphics2D
+{
+ private GtkComponentPeer component;
+ private long cairo_t;
+
+ private ComponentGraphics(GtkComponentPeer component)
+ {
+ this.component = component;
+ cairo_t = initState(component);
+ setup( cairo_t );
+ Rectangle bounds = component.awtComponent.getBounds();
+ setClip( new Rectangle( 0, 0, bounds.width, bounds.height) );
+ setBackground(component.awtComponent.getBackground());
+ setColor(component.awtComponent.getForeground());
+ }
+
+ private ComponentGraphics(ComponentGraphics cg)
+ {
+ component = cg.component;
+ cairo_t = initState(component);
+ copy( cg, cairo_t );
+ Rectangle bounds = component.awtComponent.getBounds();
+ setClip( new Rectangle( 0, 0, bounds.width, bounds.height) );
+ setBackground(component.awtComponent.getBackground());
+ setColor(component.awtComponent.getForeground());
+ }
+
+ /**
+ * Creates a cairo_t for the component surface and return it.
+ */
+ private native long initState(GtkComponentPeer component);
+
+ /**
+ * Grab lock
+ */
+ private native void start_gdk_drawing();
+
+ /**
+ * Release lock
+ */
+ private native void end_gdk_drawing();
+
+ /**
+ * Query if the system has the XRender extension.
+ */
+ public static native boolean hasXRender();
+
+
+ private native void copyAreaNative(GtkComponentPeer component, int x, int y,
+ int width, int height, int dx, int dy);
+
+ private native void drawVolatile(GtkComponentPeer component,
+ Image vimg, int x, int y,
+ int width, int height);
+
+ /**
+ * Returns a Graphics2D object for a component, either an instance of this
+ * class (if xrender is supported), or a context which copies.
+ */
+ public static Graphics2D getComponentGraphics(GtkComponentPeer component)
+ {
+ if( hasXRender() )
+ return new ComponentGraphics(component);
+
+ Rectangle r = component.awtComponent.getBounds();
+ return new ComponentGraphicsCopy(r.width, r.height, component);
+ }
+
+ public GraphicsConfiguration getDeviceConfiguration()
+ {
+ return component.getGraphicsConfiguration();
+ }
+
+ public Graphics create()
+ {
+ return new ComponentGraphics(this);
+ }
+
+ protected Rectangle2D getRealBounds()
+ {
+ return component.awtComponent.getBounds();
+ }
+
+ public void copyAreaImpl(int x, int y, int width, int height, int dx, int dy)
+ {
+ copyAreaNative(component, x, y, width, height, dx, dy);
+ }
+
+ /**
+ * Overloaded methods that do actual drawing need to enter the gdk threads
+ * and also do certain things before and after.
+ */
+ public void draw(Shape s)
+ {
+ start_gdk_drawing();
+ super.draw(s);
+ end_gdk_drawing();
+ }
+
+ public void fill(Shape s)
+ {
+ start_gdk_drawing();
+ super.fill(s);
+ end_gdk_drawing();
+ }
+
+ public void drawRenderedImage(RenderedImage image, AffineTransform xform)
+ {
+ start_gdk_drawing();
+ super.drawRenderedImage(image, xform);
+ end_gdk_drawing();
+ }
+
+ protected boolean drawImage(Image img, AffineTransform xform,
+ Color bgcolor, ImageObserver obs)
+ {
+ start_gdk_drawing();
+ boolean rv = super.drawImage(img, xform, bgcolor, obs);
+ end_gdk_drawing();
+ return rv;
+ }
+
+ public void drawGlyphVector(GlyphVector gv, float x, float y)
+ {
+ start_gdk_drawing();
+ super.drawGlyphVector(gv, x, y);
+ end_gdk_drawing();
+ }
+
+ public boolean drawImage(Image img, int x, int y, ImageObserver observer)
+ {
+ if( img instanceof GtkVolatileImage )
+ {
+ ((GtkVolatileImage)img).validate( null );
+ drawVolatile( component, img, x, y-20 ,
+ ((GtkVolatileImage)img).width,
+ ((GtkVolatileImage)img).height );
+ return true;
+ }
+ return super.drawImage( img, x, y, observer );
+ }
+
+ public boolean drawImage(Image img, int x, int y, int width, int height,
+ ImageObserver observer)
+ {
+ if( img instanceof GtkVolatileImage )
+ {
+ ((GtkVolatileImage)img).validate( null );
+ drawVolatile( component, img, x, y-20,
+ width, height );
+ return true;
+ }
+ return super.drawImage( img, x, y, width, height, observer );
+ }
+
+}
+
diff --git a/gnu/java/awt/peer/gtk/ComponentGraphicsCopy.java b/gnu/java/awt/peer/gtk/ComponentGraphicsCopy.java
new file mode 100644
index 000000000..286fbeac0
--- /dev/null
+++ b/gnu/java/awt/peer/gtk/ComponentGraphicsCopy.java
@@ -0,0 +1,129 @@
+/* ComponentGraphicsCopy.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.java.awt.peer.gtk;
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.font.GlyphVector;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBuffer;
+import java.awt.image.RenderedImage;
+import java.awt.image.ImageObserver;
+
+/**
+ * Implementation of Graphics2D for Components for servers which
+ * do not have xrender.
+ *
+ * A mirrored GtkImage of the component is stored in memory
+ * and copied back. Yay.
+ */
+public class ComponentGraphicsCopy extends CairoSurfaceGraphics
+{
+ private GtkComponentPeer component;
+
+ /**
+ * GtkImage sharing its data buffer with this Cairo surface.
+ */
+ private GtkImage gtkimage;
+
+ private int width, height;
+
+ native void getPixbuf( GtkComponentPeer component, GtkImage image );
+
+ native void copyPixbuf( GtkComponentPeer component, GtkImage image,
+ int x, int y, int w, int h );
+
+ public ComponentGraphicsCopy(int width, int height,
+ GtkComponentPeer component)
+ {
+ super( new CairoSurface( width, height ) );
+ this.component = component;
+ this.width = width;
+ this.height = height;
+ gtkimage = surface.getGtkImage();
+ getPixbuf( component, gtkimage );
+ }
+
+ /**
+ * Overloaded methods that do actual drawing need to enter the gdk threads
+ * and also do certain things before and after.
+ */
+ public void draw(Shape s)
+ {
+ super.draw(s);
+ Rectangle r = s.getBounds();
+ copyPixbuf(component, gtkimage, r.x, r.y, r.width, r.height);
+ }
+
+ public void fill(Shape s)
+ {
+ super.fill(s);
+ Rectangle r = s.getBounds();
+ copyPixbuf(component, gtkimage, r.x, r.y, r.width, r.height);
+ }
+
+ public void drawRenderedImage(RenderedImage image, AffineTransform xform)
+ {
+ super.drawRenderedImage(image, xform);
+ copyPixbuf(component, gtkimage, 0, 0, width, height);
+ }
+
+ protected boolean drawImage(Image img, AffineTransform xform,
+ Color bgcolor, ImageObserver obs)
+ {
+ boolean rv = super.drawImage(img, xform, bgcolor, obs);
+ copyPixbuf(component, gtkimage, 0, 0, width, height);
+ return rv;
+ }
+
+ public void drawGlyphVector(GlyphVector gv, float x, float y)
+ {
+ super.drawGlyphVector(gv, x, y);
+ Rectangle r = gv.getPixelBounds(getFontRenderContext(), x , y);
+ copyPixbuf(component, gtkimage, r.x, r.y, r.width, r.height);
+ }
+}
+
diff --git a/gnu/java/awt/peer/gtk/GdkFontPeer.java b/gnu/java/awt/peer/gtk/GdkFontPeer.java
index 82744480d..4781cb067 100644
--- a/gnu/java/awt/peer/gtk/GdkFontPeer.java
+++ b/gnu/java/awt/peer/gtk/GdkFontPeer.java
@@ -40,6 +40,7 @@ package gnu.java.awt.peer.gtk;
import gnu.classpath.Configuration;
import gnu.java.awt.peer.ClasspathFontPeer;
+import gnu.java.awt.font.opentype.NameDecoder;
import java.awt.Font;
import java.awt.FontMetrics;
@@ -53,6 +54,7 @@ import java.text.StringCharacterIterator;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
+import java.nio.ByteBuffer;
public class GdkFontPeer extends ClasspathFontPeer
{
@@ -62,10 +64,7 @@ public class GdkFontPeer extends ClasspathFontPeer
static
{
- if (Configuration.INIT_LOAD_LIBRARY)
- {
- System.loadLibrary("gtkpeer");
- }
+ System.loadLibrary("gtkpeer");
initStaticState ();
@@ -79,17 +78,21 @@ public class GdkFontPeer extends ClasspathFontPeer
}
}
+ private ByteBuffer nameTable = null;
+
private native void initState ();
private native void dispose ();
- private native void setFont (String family, int style, int size, boolean useGraphics2D);
+ private native void setFont (String family, int style, int size);
native void getFontMetrics(double [] metrics);
native void getTextMetrics(String str, double [] metrics);
+ native void releasePeerGraphicsResource();
+
+
protected void finalize ()
{
- if (GtkToolkit.useGraphics2D ())
- GdkGraphics2D.releasePeerGraphicsResource(this);
+ releasePeerGraphicsResource();
dispose ();
}
@@ -139,26 +142,84 @@ public class GdkFontPeer extends ClasspathFontPeer
{
super(name, style, size);
initState ();
- setFont (this.familyName, this.style, (int)this.size,
- GtkToolkit.useGraphics2D());
+ setFont (this.familyName, this.style, (int)this.size);
}
public GdkFontPeer (String name, Map attributes)
{
super(name, attributes);
initState ();
- setFont (this.familyName, this.style, (int)this.size,
- GtkToolkit.useGraphics2D());
+ setFont (this.familyName, this.style, (int)this.size);
}
-
+
+ /**
+ * Unneeded, but implemented anyway.
+ */
public String getSubFamilyName(Font font, Locale locale)
{
- return null;
+ String name;
+
+ if (locale == null)
+ locale = Locale.getDefault();
+
+ name = getName(NameDecoder.NAME_SUBFAMILY, locale);
+ if (name == null)
+ {
+ name = getName(NameDecoder.NAME_SUBFAMILY, Locale.ENGLISH);
+ if ("Regular".equals(name))
+ name = null;
+ }
+
+ return name;
}
+ /**
+ * Returns the bytes belonging to a TrueType/OpenType table,
+ * Parameters n,a,m,e identify the 4-byte ASCII tag of the table.
+ *
+ * Returns null if the font is not TT, the table is nonexistant,
+ * or if some other unexpected error occured.
+ *
+ */
+ private native byte[] getTrueTypeTable(byte n, byte a, byte m, byte e);
+
+ /**
+ * Returns the PostScript name of the font, defaults to the familyName if
+ * a PS name could not be retrieved.
+ */
public String getPostScriptName(Font font)
{
- return this.familyName;
+ String name = getName(NameDecoder.NAME_POSTSCRIPT,
+ /* any language */ null);
+ if( name == null )
+ return this.familyName;
+
+ return name;
+ }
+
+ /**
+ * Extracts a String from the font&#x2019;s name table.
+ *
+ * @param name the numeric TrueType or OpenType name ID.
+ *
+ * @param locale the locale for which names shall be localized, or
+ * <code>null</code> if the locale does mot matter because the name
+ * is known to be language-independent (for example, because it is
+ * the PostScript name).
+ */
+ private String getName(int name, Locale locale)
+ {
+ if (nameTable == null)
+ {
+ byte[] data = getTrueTypeTable((byte)'n', (byte) 'a',
+ (byte) 'm', (byte) 'e');
+ if( data == null )
+ return null;
+
+ nameTable = ByteBuffer.wrap( data );
+ }
+
+ return NameDecoder.getName(nameTable, name, locale);
}
public boolean canDisplay (Font font, char c)
@@ -265,7 +326,13 @@ public class GdkFontPeer extends ClasspathFontPeer
public int getNumGlyphs (Font font)
{
- throw new UnsupportedOperationException ();
+ byte[] data = getTrueTypeTable((byte)'m', (byte) 'a',
+ (byte)'x', (byte) 'p');
+ if( data == null )
+ return -1;
+
+ ByteBuffer buf = ByteBuffer.wrap( data );
+ return buf.getShort(4);
}
public Rectangle2D getStringBounds (Font font, CharacterIterator ci,
diff --git a/gnu/java/awt/peer/gtk/GdkGraphics.java b/gnu/java/awt/peer/gtk/GdkGraphics.java
deleted file mode 100644
index 3c3cbdf32..000000000
--- a/gnu/java/awt/peer/gtk/GdkGraphics.java
+++ /dev/null
@@ -1,496 +0,0 @@
-/* GdkGraphics.java
- Copyright (C) 1998, 1999, 2002, 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 gnu.java.awt.peer.gtk;
-
-import gnu.classpath.Configuration;
-
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Graphics;
-import java.awt.Image;
-import java.awt.Rectangle;
-import java.awt.Shape;
-import java.awt.Toolkit;
-import java.awt.image.ImageObserver;
-import java.text.AttributedCharacterIterator;
-
-public class GdkGraphics extends Graphics
-{
- static
- {
- if (Configuration.INIT_LOAD_LIBRARY)
- {
- System.loadLibrary("gtkpeer");
- }
- initStaticState ();
- }
-
- static native void initStaticState();
- private final int native_state = GtkGenericPeer.getUniqueInteger ();
-
- Color color, xorColor;
- GtkComponentPeer component;
- Font font = new Font ("Dialog", Font.PLAIN, 12);
- Rectangle clip;
- GtkImage image;
-
- int xOffset = 0;
- int yOffset = 0;
-
- static final int GDK_COPY = 0, GDK_XOR = 2;
-
- native void initState (GtkComponentPeer component);
- native void initStateUnlocked (GtkComponentPeer component);
- native void initState (int width, int height);
- native void initFromImage (GtkImage image);
- native void nativeCopyState (GdkGraphics g);
-
- /**
- * A cached instance that is used by {@link #create} in order to avoid
- * massive allocation of graphics contexts.
- */
- GdkGraphics cached = null;
-
- /**
- * A link to the parent context. This is used in {@link #dispose} to put
- * this graphics context into the cache.
- */
- GdkGraphics parent = null;
-
- GdkGraphics (GdkGraphics g)
- {
- parent = g;
- copyState (g);
- }
-
- GdkGraphics (int width, int height)
- {
- initState (width, height);
- color = Color.black;
- clip = new Rectangle (0, 0, width, height);
- font = new Font ("Dialog", Font.PLAIN, 12);
- }
-
- GdkGraphics (GtkImage image)
- {
- this.image = image;
- initFromImage (image);
- color = Color.black;
- clip = new Rectangle (0, 0,
- image.getWidth(null), image.getHeight(null));
- font = new Font ("Dialog", Font.PLAIN, 12);
- }
-
- GdkGraphics (GtkComponentPeer component)
- {
- this.component = component;
- color = Color.black;
-
- if (component.isRealized ())
- initComponentGraphics ();
- else
- connectSignals (component);
- }
-
- void initComponentGraphics ()
- {
- initState (component);
- color = component.awtComponent.getForeground ();
- if (color == null)
- color = Color.BLACK;
- Dimension d = component.awtComponent.getSize ();
- clip = new Rectangle (0, 0, d.width, d.height);
- }
-
- // called back by native side: realize_cb
- void initComponentGraphicsUnlocked ()
- {
- initStateUnlocked (component);
- color = component.awtComponent.getForeground ();
- if (color == null)
- color = Color.BLACK;
- Dimension d = component.awtComponent.getSize ();
- clip = new Rectangle (0, 0, d.width, d.height);
- }
-
- native void connectSignals (GtkComponentPeer component);
-
- public native void clearRect(int x, int y, int width, int height);
-
- public void clipRect (int x, int y, int width, int height)
- {
- if (component != null && ! component.isRealized ())
- return;
-
- clip = clip.intersection (new Rectangle (x, y, width, height));
- setClipRectangle (clip.x, clip.y, clip.width, clip.height);
- }
-
- public native void copyArea(int x, int y, int width, int height,
- int dx, int dy);
-
- /**
- * Creates a copy of this GdkGraphics instance. This implementation can
- * reuse a cached instance to avoid massive instantiation of Graphics objects
- * during painting.
- *
- * @return a copy of this graphics context
- */
- public Graphics create()
- {
- GdkGraphics copy = cached;
- if (copy == null)
- copy = new GdkGraphics(this);
- else
- {
- copy.copyState(this);
- cached = null;
- }
- return copy;
- }
-
- public native void nativeDispose();
-
- /**
- * Disposes this graphics object. This puts this graphics context into the
- * cache of its parent graphics if there is one.
- */
- public void dispose()
- {
- if (parent != null)
- {
- parent.cached = this;
- parent = null;
- }
- else
- nativeDispose();
- }
-
- /**
- * This is called when this object gets finalized by the garbage collector.
- * In addition to {@link Graphics#finalize()} this calls nativeDispose() to
- * make sure the native resources are freed before the graphics context is
- * thrown away.
- */
- public void finalize()
- {
- super.finalize();
- nativeDispose();
- }
-
- public boolean drawImage (Image img, int x, int y,
- Color bgcolor, ImageObserver observer)
- {
- if (img != null)
- return drawImage(img, x, y, img.getWidth(null), img.getHeight(null),
- bgcolor, observer);
- return false;
- }
-
- public boolean drawImage (Image img, int x, int y, ImageObserver observer)
- {
- return drawImage (img, x, y, null, observer);
- }
-
- public boolean drawImage(Image img, int x, int y, int width, int height,
- Color bgcolor, ImageObserver observer)
- {
- if (img != null)
- {
- if (img instanceof GtkImage)
- return ((GtkImage) img).drawImage(this, x, y, width, height, bgcolor,
- observer);
- return (new GtkImage(img.getSource())).drawImage(this, x, y, width,
- height, bgcolor,
- observer);
- }
- return false;
- }
-
- public boolean drawImage (Image img, int x, int y, int width, int height,
- ImageObserver observer)
- {
- return drawImage (img, x, y, width, height, null, observer);
- }
-
- public boolean drawImage (Image img, int dx1, int dy1, int dx2, int dy2,
- int sx1, int sy1, int sx2, int sy2,
- Color bgcolor, ImageObserver observer)
- {
- if (img != null)
- {
- if (img instanceof GtkImage)
- return ((GtkImage) img).drawImage(this, dx1, dy1, dx2, dy2, sx1, sy1,
- sx2, sy2, bgcolor, observer);
- return (new GtkImage(img.getSource())).drawImage(this, dx1, dy1, dx2,
- dy2, sx1, sy1, sx2,
- sy2, bgcolor, observer);
- }
- return false;
- }
-
- public boolean drawImage (Image img, int dx1, int dy1, int dx2, int dy2,
- int sx1, int sy1, int sx2, int sy2,
- ImageObserver observer)
- {
- return drawImage (img, dx1, dy1, dx2, dy2,
- sx1, sy1, sx2, sy2,
- null, observer);
- }
-
- public native void drawLine(int x1, int y1, int x2, int y2);
-
- public native void drawArc(int x, int y, int width, int height,
- int startAngle, int arcAngle);
- public native void fillArc(int x, int y, int width, int height,
- int startAngle, int arcAngle);
- public native void drawOval(int x, int y, int width, int height);
- public native void fillOval(int x, int y, int width, int height);
-
- public native void drawPolygon(int[] xPoints, int[] yPoints, int nPoints);
- public native void fillPolygon(int[] xPoints, int[] yPoints, int nPoints);
-
- public native void drawPolyline(int[] xPoints, int[] yPoints, int nPoints);
-
- public native void drawRect(int x, int y, int width, int height);
- public native void fillRect(int x, int y, int width, int height);
-
- GdkFontPeer getFontPeer()
- {
- return (GdkFontPeer) getFont().getPeer();
- }
-
- native void drawString (GdkFontPeer f, String str, int x, int y);
- public void drawString (String str, int x, int y)
- {
- drawString(getFontPeer(), str, x, y);
- }
-
- public void drawString (AttributedCharacterIterator ci, int x, int y)
- {
- throw new Error ("not implemented");
- }
-
- public void drawRoundRect(int x, int y, int width, int height,
- int arcWidth, int arcHeight)
- {
- if (arcWidth > width)
- arcWidth = width;
- if (arcHeight > height)
- arcHeight = height;
-
- int xx = x + width - arcWidth;
- int yy = y + height - arcHeight;
-
- drawArc (x, y, arcWidth, arcHeight, 90, 90);
- drawArc (xx, y, arcWidth, arcHeight, 0, 90);
- drawArc (xx, yy, arcWidth, arcHeight, 270, 90);
- drawArc (x, yy, arcWidth, arcHeight, 180, 90);
-
- int y1 = y + arcHeight / 2;
- int y2 = y + height - arcHeight / 2;
- drawLine (x, y1, x, y2);
- drawLine (x + width, y1, x + width, y2);
-
- int x1 = x + arcWidth / 2;
- int x2 = x + width - arcWidth / 2;
- drawLine (x1, y, x2, y);
- drawLine (x1, y + height, x2, y + height);
- }
-
- public void fillRoundRect (int x, int y, int width, int height,
- int arcWidth, int arcHeight)
- {
- if (arcWidth > width)
- arcWidth = width;
- if (arcHeight > height)
- arcHeight = height;
-
- int xx = x + width - arcWidth;
- int yy = y + height - arcHeight;
-
- fillArc (x, y, arcWidth, arcHeight, 90, 90);
- fillArc (xx, y, arcWidth, arcHeight, 0, 90);
- fillArc (xx, yy, arcWidth, arcHeight, 270, 90);
- fillArc (x, yy, arcWidth, arcHeight, 180, 90);
-
- fillRect (x, y + arcHeight / 2, width, height - arcHeight + 1);
- fillRect (x + arcWidth / 2, y, width - arcWidth + 1, height);
- }
-
- public Shape getClip ()
- {
- return getClipBounds ();
- }
-
- public Rectangle getClipBounds ()
- {
- if (clip == null)
- return null;
- else
- return clip.getBounds();
- }
-
- public Color getColor ()
- {
- return color;
- }
-
- public Font getFont ()
- {
- return font;
- }
-
- public FontMetrics getFontMetrics (Font font)
- {
- // Get the font metrics through GtkToolkit to take advantage of
- // the metrics cache.
- return Toolkit.getDefaultToolkit().getFontMetrics (font);
- }
-
- native void setClipRectangle (int x, int y, int width, int height);
-
- public void setClip (int x, int y, int width, int height)
- {
- if ((component != null && ! component.isRealized ())
- || clip == null)
- return;
-
- clip.x = x;
- clip.y = y;
- clip.width = width;
- clip.height = height;
-
- setClipRectangle (x, y, width, height);
- }
-
- public void setClip (Rectangle clip)
- {
- setClip (clip.x, clip.y, clip.width, clip.height);
- }
-
- public void setClip (Shape clip)
- {
- if (clip == null)
- {
- // Reset clipping.
- Dimension d = component.awtComponent.getSize();
- setClip(new Rectangle (0, 0, d.width, d.height));
- }
- else
- setClip(clip.getBounds());
- }
-
- private native void setFGColor(int red, int green, int blue);
-
- public void setColor (Color c)
- {
- if (c == null)
- color = Color.BLACK;
- else
- color = c;
-
- if (xorColor == null) /* paint mode */
- setFGColor (color.getRed (), color.getGreen (), color.getBlue ());
- else /* xor mode */
- setFGColor (color.getRed () ^ xorColor.getRed (),
- color.getGreen () ^ xorColor.getGreen (),
- color.getBlue () ^ xorColor.getBlue ());
- }
-
- public void setFont (Font font)
- {
- if (font != null)
- this.font = font;
- }
-
- native void setFunction (int gdk_func);
-
- public void setPaintMode ()
- {
- xorColor = null;
-
- setFunction (GDK_COPY);
- setFGColor (color.getRed (), color.getGreen (), color.getBlue ());
- }
-
- public void setXORMode (Color c)
- {
- xorColor = c;
-
- setFunction (GDK_XOR);
- setFGColor (color.getRed () ^ xorColor.getRed (),
- color.getGreen () ^ xorColor.getGreen (),
- color.getBlue () ^ xorColor.getBlue ());
- }
-
- public native void translateNative(int x, int y);
-
- public void translate (int x, int y)
- {
- if (component != null && ! component.isRealized ())
- return;
-
- clip.x -= x;
- clip.y -= y;
-
- translateNative (x, y);
- }
-
- /**
- * Copies over the state of another GdkGraphics to this instance. This is
- * used by the {@link #GdkGraphics(GdkGraphics)} constructor and the
- * {@link #create()} method.
- *
- * @param g the GdkGraphics object to copy the state from
- */
- private void copyState(GdkGraphics g)
- {
- color = g.color;
- xorColor = g.xorColor;
- font = g.font;
- if (font == null)
- font = new Font ("Dialog", Font.PLAIN, 12);
- clip = new Rectangle (g.clip);
- component = g.component;
- nativeCopyState(g);
- }
-}
diff --git a/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java b/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java
index 4b0b5d308..b2615a912 100644
--- a/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java
+++ b/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java
@@ -45,6 +45,7 @@ import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
+import java.awt.image.DataBuffer;
import java.util.Locale;
public class GdkGraphicsEnvironment extends GraphicsEnvironment
@@ -69,7 +70,11 @@ public class GdkGraphicsEnvironment extends GraphicsEnvironment
public Graphics2D createGraphics (BufferedImage image)
{
- return new GdkGraphics2D (image);
+ DataBuffer db = image.getRaster().getDataBuffer();
+ if(db instanceof CairoSurface)
+ return ((CairoSurface)db).getGraphics();
+
+ return new BufferedImageGraphics( image );
}
private native int nativeGetNumFontFamilies();
@@ -80,17 +85,17 @@ public class GdkGraphicsEnvironment extends GraphicsEnvironment
throw new java.lang.UnsupportedOperationException ();
}
- public String[] getAvailableFontFamilyNames ()
- {
- String[] family_names;
- int array_size;
-
- array_size = nativeGetNumFontFamilies();
- family_names = new String[array_size];
-
- nativeGetFontFamilies(family_names);
- return family_names;
- }
+ public String[] getAvailableFontFamilyNames ()
+ {
+ String[] family_names;
+ int array_size;
+
+ array_size = nativeGetNumFontFamilies();
+ family_names = new String[array_size];
+
+ nativeGetFontFamilies(family_names);
+ return family_names;
+ }
public String[] getAvailableFontFamilyNames (Locale l)
{
diff --git a/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java b/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java
index 72908ff5c..4e6181f0e 100644
--- a/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java
+++ b/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java
@@ -75,10 +75,8 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
{
static
{
- if (Configuration.INIT_LOAD_LIBRARY)
- {
- System.loadLibrary("gtkpeer");
- }
+ System.loadLibrary("gtkpeer");
+
initStaticState ();
}
@@ -504,19 +502,19 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
int width = ras.getWidth();
int height = ras.getHeight();
ColorModel model = image.getColorModel();
- int[] pixels = GdkGraphics2D.findSimpleIntegerArray (image.getColorModel(), ras);
+ int[] pixels = CairoGraphics2D.findSimpleIntegerArray (image.getColorModel(), ras);
if (pixels == null)
{
- BufferedImage img = new BufferedImage(width, height,
- (model != null && model.hasAlpha() ?
- BufferedImage.TYPE_INT_ARGB
- : BufferedImage.TYPE_INT_RGB));
+ BufferedImage img;
+ if(model != null && model.hasAlpha())
+ img = CairoSurface.getBufferedImage(width, height);
+ img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
int[] pix = new int[4];
for (int y = 0; y < height; ++y)
for (int x = 0; x < width; ++x)
img.setRGB(x, y, model.getRGB(ras.getPixel(x, y, pix)));
- pixels = GdkGraphics2D.findSimpleIntegerArray (img.getColorModel(),
+ pixels = CairoGraphics2D.findSimpleIntegerArray (img.getColorModel(),
img.getRaster());
model = img.getColorModel();
}
@@ -586,9 +584,10 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
if (bufferedImage == null)
{
- bufferedImage = new BufferedImage (width, height, (model != null && model.hasAlpha() ?
- BufferedImage.TYPE_INT_ARGB
- : BufferedImage.TYPE_INT_RGB));
+ if(model != null && model.hasAlpha())
+ bufferedImage = new BufferedImage (width, height, BufferedImage.TYPE_INT_ARGB);
+ else
+ bufferedImage = new BufferedImage (width, height, BufferedImage.TYPE_INT_RGB);
}
int pixels2[];
@@ -682,43 +681,4 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
return getBufferedImage ();
}
}
-
- // remaining helper class and static method is a convenience for the Gtk
- // peers, for loading a BufferedImage in off a disk file without going
- // through the whole imageio system.
-
- public static BufferedImage createBufferedImage (String filename)
- {
- GdkPixbufReader r = new GdkPixbufReader (getReaderSpi(),
- "png", // reader auto-detects, doesn't matter
- new GdkPixbufDecoder (filename));
- return r.getBufferedImage ();
- }
-
- public static BufferedImage createBufferedImage (URL u)
- {
- GdkPixbufReader r = new GdkPixbufReader (getReaderSpi(),
- "png", // reader auto-detects, doesn't matter
- new GdkPixbufDecoder (u));
- return r.getBufferedImage ();
- }
-
- public static BufferedImage createBufferedImage (byte[] imagedata, int imageoffset,
- int imagelength)
- {
- GdkPixbufReader r = new GdkPixbufReader (getReaderSpi(),
- "png", // reader auto-detects, doesn't matter
- new GdkPixbufDecoder (imagedata,
- imageoffset,
- imagelength));
- return r.getBufferedImage ();
- }
-
- public static BufferedImage createBufferedImage (ImageProducer producer)
- {
- GdkPixbufReader r = new GdkPixbufReader (getReaderSpi(), "png" /* ignored */, null);
- producer.startProduction(r);
- return r.getBufferedImage ();
- }
-
}
diff --git a/gnu/java/awt/peer/gtk/GdkTextLayout.java b/gnu/java/awt/peer/gtk/GdkTextLayout.java
index c3ae581b1..d6b3de8c0 100644
--- a/gnu/java/awt/peer/gtk/GdkTextLayout.java
+++ b/gnu/java/awt/peer/gtk/GdkTextLayout.java
@@ -70,20 +70,26 @@ public class GdkTextLayout
// native side, plumbing, etc.
static
{
- if (Configuration.INIT_LOAD_LIBRARY)
- {
- System.loadLibrary("gtkpeer");
- }
+ System.loadLibrary("gtkpeer");
+
initStaticState ();
}
private native void setText(String str);
+ private native void setFont(GdkFontPeer font);
private native void getExtents(double[] inkExtents,
double[] logExtents);
private native void indexToPos(int idx, double[] pos);
+
private native void initState ();
+
private native void dispose ();
+
+ private native void cairoDrawGdkTextLayout(CairoGraphics2D g, float x, float y);
+
static native void initStaticState();
+
private final int native_state = GtkGenericPeer.getUniqueInteger ();
+
protected void finalize ()
{
dispose ();
@@ -99,6 +105,15 @@ public class GdkTextLayout
initState();
attributedString = str;
fontRenderContext = frc;
+ AttributedCharacterIterator aci = str.getIterator();
+ char[] chars = new char[aci.getEndIndex() - aci.getBeginIndex()];
+ for(int i = aci.getBeginIndex(); i < aci.getEndIndex(); i++)
+ chars[i] = aci.setIndex(i);
+ setText(new String(chars));
+
+ Object fnt = aci.getAttribute(TextAttribute.FONT);
+ if (fnt != null && fnt instanceof Font)
+ setFont( (GdkFontPeer) ((Font)fnt).getPeer() );
}
protected class CharacterIteratorProxy
@@ -201,60 +216,7 @@ public class GdkTextLayout
public void draw (Graphics2D g2, float x, float y)
{
- if (g2 instanceof GdkGraphics2D)
- {
- // we share pango structures directly with GdkGraphics2D
- // when legal
- GdkGraphics2D gg2 = (GdkGraphics2D) g2;
- gg2.drawGdkTextLayout(this, x, y);
- }
- else
- {
- // falling back to a rather tedious layout algorithm when
- // not legal
- AttributedCharacterIterator ci = attributedString.getIterator ();
- CharacterIteratorProxy proxy = new CharacterIteratorProxy (ci);
- Font defFont = g2.getFont ();
-
- /* Note: this implementation currently only interprets FONT text
- * attributes. There is a reasonable argument to be made for some
- * attributes being interpreted out here, where we have control of the
- * Graphics2D and can construct or derive new fonts, and some
- * attributes being interpreted by the GlyphVector itself. So far, for
- * all attributes except FONT we do neither.
- */
-
- for (char c = ci.first ();
- c != CharacterIterator.DONE;
- c = ci.next ())
- {
- proxy.begin = ci.getIndex ();
- proxy.limit = ci.getRunLimit(TextAttribute.FONT);
- if (proxy.limit <= proxy.begin)
- continue;
-
- proxy.index = proxy.begin;
-
- Object fnt = ci.getAttribute(TextAttribute.FONT);
- GlyphVector gv;
- if (fnt instanceof Font)
- gv = ((Font)fnt).createGlyphVector (fontRenderContext, proxy);
- else
- gv = defFont.createGlyphVector (fontRenderContext, proxy);
-
- g2.drawGlyphVector (gv, x, y);
-
- int n = gv.getNumGlyphs ();
- for (int i = 0; i < n; ++i)
- {
- GlyphMetrics gm = gv.getGlyphMetrics (i);
- if (gm.getAdvanceX() == gm.getAdvance ())
- x += gm.getAdvanceX ();
- else
- y += gm.getAdvanceY ();
- }
- }
- }
+ cairoDrawGdkTextLayout((CairoGraphics2D)g2, x, y);
}
public TextHitInfo getStrongCaret (TextHitInfo hit1,
diff --git a/gnu/java/awt/peer/gtk/GtkCanvasPeer.java b/gnu/java/awt/peer/gtk/GtkCanvasPeer.java
index 797d653d2..edfc9ceee 100644
--- a/gnu/java/awt/peer/gtk/GtkCanvasPeer.java
+++ b/gnu/java/awt/peer/gtk/GtkCanvasPeer.java
@@ -45,7 +45,6 @@ import java.awt.peer.CanvasPeer;
public class GtkCanvasPeer extends GtkComponentPeer implements CanvasPeer
{
native void create ();
- native void realize ();
public GtkCanvasPeer (Canvas c)
{
diff --git a/gnu/java/awt/peer/gtk/GtkComponentPeer.java b/gnu/java/awt/peer/gtk/GtkComponentPeer.java
index 1a85de5fe..625855f01 100644
--- a/gnu/java/awt/peer/gtk/GtkComponentPeer.java
+++ b/gnu/java/awt/peer/gtk/GtkComponentPeer.java
@@ -109,14 +109,7 @@ public class GtkComponentPeer extends GtkGenericPeer
native void gtkWidgetRequestFocus ();
native void gtkWidgetDispatchKeyEvent (int id, long when, int mods,
int keyCode, int keyLocation);
-
- native boolean isRealized ();
-
- void realize ()
- {
- // Default implementation does nothing
- }
-
+ native void realize();
native void setNativeEventMask ();
void create ()
@@ -149,6 +142,9 @@ public class GtkComponentPeer extends GtkGenericPeer
setNativeEventMask ();
+ // This peer is guaranteed to have an X window upon construction.
+ // That is, native methods such as those in GdkGraphics can rely
+ // on this component's widget->window field being non-null.
realize ();
if (awtComponent.isCursorSet())
@@ -211,16 +207,7 @@ public class GtkComponentPeer extends GtkGenericPeer
public Image createImage (int width, int height)
{
- Image image;
- if (GtkToolkit.useGraphics2D ())
- image = new BufferedImage (width, height, BufferedImage.TYPE_INT_RGB);
- else
- image = new GtkImage (width, height);
-
- Graphics g = image.getGraphics();
- g.setColor(getBackground());
- g.fillRect(0, 0, width, height);
- return image;
+ return CairoSurface.getBufferedImage(width, height);
}
public void disable ()
@@ -247,10 +234,7 @@ public class GtkComponentPeer extends GtkGenericPeer
// never return null.
public Graphics getGraphics ()
{
- if (GtkToolkit.useGraphics2D ())
- return new GdkGraphics2D (this);
- else
- return new GdkGraphics (this);
+ return ComponentGraphics.getComponentGraphics(this);
}
public Point getLocationOnScreen ()
@@ -713,7 +697,7 @@ public class GtkComponentPeer extends GtkGenericPeer
// on which this component is displayed.
public VolatileImage createVolatileImage (int width, int height)
{
- return new GtkVolatileImage (width, height);
+ return new GtkVolatileImage (this, width, height, null);
}
// Creates buffers used in a buffering strategy.
@@ -723,7 +707,7 @@ public class GtkComponentPeer extends GtkGenericPeer
// numBuffers == 2 implies double-buffering, meaning one back
// buffer and one front buffer.
if (numBuffers == 2)
- backBuffer = new GtkVolatileImage(awtComponent.getWidth(),
+ backBuffer = new GtkVolatileImage(this, awtComponent.getWidth(),
awtComponent.getHeight(),
caps.getBackBufferCapabilities());
else
diff --git a/gnu/java/awt/peer/gtk/GtkImage.java b/gnu/java/awt/peer/gtk/GtkImage.java
index 5e5f1de01..ef96518a1 100644
--- a/gnu/java/awt/peer/gtk/GtkImage.java
+++ b/gnu/java/awt/peer/gtk/GtkImage.java
@@ -57,14 +57,7 @@ import java.net.URL;
import gnu.classpath.Pointer;
/**
- * GtkImage - wraps a GdkPixbuf or GdkPixmap.
- *
- * The constructor GtkImage(int, int) creates an 'off-screen' GdkPixmap,
- * this can be drawn to (it's a GdkDrawable), and correspondingly, you can
- * create a GdkGraphics object for it.
- *
- * This corresponds to the Image implementation returned by
- * Component.createImage(int, int).
+ * GtkImage - wraps a GdkPixbuf.
*
* A GdkPixbuf is 'on-screen' and the gdk cannot draw to it,
* this is used for the other constructors (and other createImage methods), and
@@ -88,9 +81,10 @@ public class GtkImage extends Image
boolean isLoaded;
/**
- * Pointer to the GdkPixbuf
+ * Pointer to the GdkPixbuf -
+ * don't change the name without changing the native code.
*/
- Pointer pixmap;
+ Pointer pixbuf;
/**
* Observer queue.
@@ -98,11 +92,6 @@ public class GtkImage extends Image
Vector observers;
/**
- * If offScreen is set, a GdkBitmap is wrapped and not a Pixbuf.
- */
- boolean offScreen;
-
- /**
* Error flag for loading.
*/
boolean errorLoading;
@@ -122,71 +111,64 @@ public class GtkImage extends Image
0xFF000000);
/**
+ * The singleton GtkImage that is returned on errors by GtkToolkit.
+ */
+ private static GtkImage errorImage;
+
+ /**
+ * Lock that should be held for all gdkpixbuf operations. We don't use
+ * the global gdk_threads_enter/leave functions in most places since
+ * most gdkpixbuf operations can be done in parallel to drawing and
+ * manipulating gtk widgets.
+ */
+ static Object pixbufLock = new Object();
+
+ /**
+ * Allocate a PixBuf from a given ARGB32 buffer pointer.
+ */
+ private native void initFromBuffer( long bufferPointer );
+
+ /**
* Returns a copy of the pixel data as a java array.
- * Should be called with the GdkPixbufDecoder.pixbufLock held.
+ * Should be called with the pixbufLock held.
*/
- private native int[] getPixels();
+ native int[] getPixels();
/**
* Sets the pixel data from a java array.
- * Should be called with the GdkPixbufDecoder.pixbufLock held.
+ * Should be called with the pixbufLock held.
*/
private native void setPixels(int[] pixels);
/**
* Loads an image using gdk-pixbuf from a file.
- * Should be called with the GdkPixbufDecoder.pixbufLock held.
+ * Should be called with the pixbufLock held.
*/
private native boolean loadPixbuf(String name);
/**
* Loads an image using gdk-pixbuf from data.
- * Should be called with the GdkPixbufDecoder.pixbufLock held.
+ * Should be called with the pixbufLock held.
*/
private native boolean loadImageFromData(byte[] data);
/**
- * Allocates a Gtk Pixbuf or pixmap
- * Should be called with the GdkPixbufDecoder.pixbufLock held.
+ * Allocates a Gtk Pixbuf
+ * Should be called with the pixbufLock held.
*/
- private native void createPixmap();
+ private native void createPixbuf();
/**
* Frees the above.
- * Should be called with the GdkPixbufDecoder.pixbufLock held.
- */
- private native void freePixmap();
-
- /**
- * Sets the pixmap to scaled copy of src image. hints are rendering hints.
- * Should be called with the GdkPixbufDecoder.pixbufLock held.
- */
- private native void createScaledPixmap(GtkImage src, int hints);
-
- /**
- * Draws the image, optionally scaled and composited.
- * Should be called with the GdkPixbufDecoder.pixbufLock held.
- * Also acquires global gdk lock for drawing.
+ * Should be called with the pixbufLock held.
*/
- private native void drawPixelsScaled (GdkGraphics gc,
- int bg_red, int bg_green, int bg_blue,
- int x, int y, int width, int height,
- boolean composite);
+ private native void freePixbuf();
/**
- * Draws the image, optionally scaled flipped and composited.
- * Should be called with the GdkPixbufDecoder.pixbufLock held.
- * Also acquires global gdk lock for drawing.
+ * Sets the pixbuf to scaled copy of src image. hints are rendering hints.
+ * Should be called with the pixbufLock held.
*/
- private native void drawPixelsScaledFlipped (GdkGraphics gc,
- int bg_red, int bg_green,
- int bg_blue,
- boolean flipX, boolean flipY,
- int srcX, int srcY,
- int srcWidth, int srcHeight,
- int dstX, int dstY,
- int dstWidth, int dstHeight,
- boolean composite);
+ private native void createScaledPixbuf(GtkImage src, int hints);
/**
* Constructs a GtkImage from an ImageProducer. Asynchronity is handled in
@@ -202,7 +184,6 @@ public class GtkImage extends Image
source = producer;
errorLoading = false;
source.startProduction(new GtkImageConsumer(this, source));
- offScreen = false;
}
/**
@@ -215,7 +196,6 @@ public class GtkImage extends Image
{
isLoaded = true;
observers = null;
- offScreen = false;
props = new Hashtable();
errorLoading = false;
}
@@ -231,7 +211,7 @@ public class GtkImage extends Image
try
{
String path = f.getCanonicalPath();
- synchronized(GdkPixbufDecoder.pixbufLock)
+ synchronized(pixbufLock)
{
if (loadPixbuf(f.getCanonicalPath()) != true)
throw new IllegalArgumentException("Couldn't load image: "
@@ -249,7 +229,6 @@ public class GtkImage extends Image
isLoaded = true;
observers = null;
- offScreen = false;
props = new Hashtable();
}
@@ -261,7 +240,7 @@ public class GtkImage extends Image
*/
public GtkImage (byte[] data)
{
- synchronized(GdkPixbufDecoder.pixbufLock)
+ synchronized(pixbufLock)
{
if (loadImageFromData (data) != true)
throw new IllegalArgumentException ("Couldn't load image.");
@@ -269,7 +248,6 @@ public class GtkImage extends Image
isLoaded = true;
observers = null;
- offScreen = false;
props = new Hashtable();
errorLoading = false;
}
@@ -301,7 +279,7 @@ public class GtkImage extends Image
throw new IllegalArgumentException ("Couldn't load image.");
}
byte[] array = baos.toByteArray();
- synchronized(GdkPixbufDecoder.pixbufLock)
+ synchronized(pixbufLock)
{
if (loadImageFromData(array) != true)
throw new IllegalArgumentException ("Couldn't load image.");
@@ -313,23 +291,6 @@ public class GtkImage extends Image
}
/**
- * Constructs an empty GtkImage.
- */
- public GtkImage (int width, int height)
- {
- this.width = width;
- this.height = height;
- props = new Hashtable();
- isLoaded = true;
- observers = null;
- offScreen = true;
- synchronized(GdkPixbufDecoder.pixbufLock)
- {
- createPixmap();
- }
- }
-
- /**
* Constructs a scaled version of the src bitmap, using the GDK.
*/
private GtkImage (GtkImage src, int width, int height, int hints)
@@ -339,12 +300,11 @@ public class GtkImage extends Image
props = new Hashtable();
isLoaded = true;
observers = null;
- offScreen = false;
// Use the GDK scaling method.
- synchronized(GdkPixbufDecoder.pixbufLock)
+ synchronized(pixbufLock)
{
- createScaledPixmap(src, hints);
+ createScaledPixbuf(src, hints);
}
}
@@ -354,19 +314,30 @@ public class GtkImage extends Image
*/
GtkImage (Pointer pixbuf)
{
- pixmap = pixbuf;
- synchronized(GdkPixbufDecoder.pixbufLock)
+ this.pixbuf = pixbuf;
+ synchronized(pixbufLock)
{
createFromPixbuf();
}
isLoaded = true;
observers = null;
- offScreen = false;
props = new Hashtable();
}
- // The singleton GtkImage that is returned on errors by GtkToolkit.
- private static GtkImage errorImage;
+ /**
+ * Wraps a buffer with a GtkImage.
+ *
+ * @param bufferPointer a pointer to an ARGB32 buffer
+ */
+ GtkImage(int width, int height, long bufferPointer)
+ {
+ this.width = width;
+ this.height = height;
+ props = new Hashtable();
+ isLoaded = true;
+ observers = null;
+ initFromBuffer( bufferPointer );
+ }
/**
* Returns an empty GtkImage with the errorLoading flag set.
@@ -385,7 +356,7 @@ public class GtkImage extends Image
/**
* Native helper function for constructor that takes a pixbuf Pointer.
- * Should be called with the GdkPixbufDecoder.pixbufLock held.
+ * Should be called with the pixbufLock held.
*/
private native void createFromPixbuf();
@@ -407,9 +378,9 @@ public class GtkImage extends Image
isLoaded = true;
deliver();
- synchronized(GdkPixbufDecoder.pixbufLock)
+ synchronized(pixbufLock)
{
- createPixmap();
+ createPixbuf();
setPixels(pixels);
}
}
@@ -450,30 +421,28 @@ public class GtkImage extends Image
return null;
int[] pixels;
- synchronized(GdkPixbufDecoder.pixbufLock)
+ synchronized (pixbufLock)
{
- pixels = getPixels();
+ if (!errorLoading)
+ pixels = getPixels();
+ else
+ return null;
}
return new MemoryImageSource(width, height, nativeModel, pixels,
0, width);
}
/**
- * Creates a GdkGraphics context for this pixmap.
+ * Does nothing. Should not be called.
*/
public Graphics getGraphics ()
{
- if (!isLoaded)
- return null;
- if (offScreen)
- return new GdkGraphics(this);
- else
- throw new IllegalAccessError("This method only works for off-screen"
- +" Images.");
+ throw new IllegalAccessError("This method only works for off-screen"
+ +" Images.");
}
/**
- * Returns a scaled instance of this pixmap.
+ * Returns a scaled instance of this pixbuf.
*/
public Image getScaledInstance(int width,
int height,
@@ -500,9 +469,9 @@ public class GtkImage extends Image
{
observers = new Vector();
isLoaded = false;
- synchronized(GdkPixbufDecoder.pixbufLock)
+ synchronized(pixbufLock)
{
- freePixmap();
+ freePixbuf();
}
source.startProduction(new GtkImageConsumer(this, source));
}
@@ -512,9 +481,9 @@ public class GtkImage extends Image
{
if (isLoaded)
{
- synchronized(GdkPixbufDecoder.pixbufLock)
+ synchronized(pixbufLock)
{
- freePixmap();
+ freePixbuf();
}
}
}
@@ -535,104 +504,6 @@ public class GtkImage extends Image
return ImageObserver.ALLBITS | ImageObserver.WIDTH | ImageObserver.HEIGHT;
}
- // Drawing methods ////////////////////////////////////////////////
-
- /**
- * Draws an image with eventual scaling/transforming.
- */
- public boolean drawImage (GdkGraphics g, int dx1, int dy1, int dx2, int dy2,
- int sx1, int sy1, int sx2, int sy2,
- Color bgcolor, ImageObserver observer)
- {
- if (addObserver(observer))
- return false;
-
- boolean flipX = (dx1 > dx2)^(sx1 > sx2);
- boolean flipY = (dy1 > dy2)^(sy1 > sy2);
- int dstWidth = Math.abs (dx2 - dx1);
- int dstHeight = Math.abs (dy2 - dy1);
- int srcWidth = Math.abs (sx2 - sx1);
- int srcHeight = Math.abs (sy2 - sy1);
- int srcX = (sx1 < sx2) ? sx1 : sx2;
- int srcY = (sy1 < sy2) ? sy1 : sy2;
- int dstX = (dx1 < dx2) ? dx1 : dx2;
- int dstY = (dy1 < dy2) ? dy1 : dy2;
-
- // Clipping. This requires the dst to be scaled as well,
- if (srcWidth > width)
- {
- dstWidth = (int)((double)dstWidth*((double)width/(double)srcWidth));
- srcWidth = width - srcX;
- }
-
- if (srcHeight > height)
- {
- dstHeight = (int)((double)dstHeight*((double)height/(double)srcHeight));
- srcHeight = height - srcY;
- }
-
- if (srcWidth + srcX > width)
- {
- dstWidth = (int)((double)dstWidth * (double)(width - srcX)/(double)srcWidth);
- srcWidth = width - srcX;
- }
-
- if (srcHeight + srcY > height)
- {
- dstHeight = (int)((double)dstHeight * (double)(width - srcY)/(double)srcHeight);
- srcHeight = height - srcY;
- }
-
- if ( this.width <= 0 || this.height <= 0 )
- return true;
-
- if ( srcWidth <= 0 || srcHeight <= 0 || dstWidth <= 0 || dstHeight <= 0)
- return true;
-
- synchronized(GdkPixbufDecoder.pixbufLock)
- {
- if(bgcolor != null)
- drawPixelsScaledFlipped (g, bgcolor.getRed (), bgcolor.getGreen (),
- bgcolor.getBlue (),
- flipX, flipY,
- srcX, srcY,
- srcWidth, srcHeight,
- dstX, dstY,
- dstWidth, dstHeight,
- true);
- else
- drawPixelsScaledFlipped (g, 0, 0, 0, flipX, flipY,
- srcX, srcY, srcWidth, srcHeight,
- dstX, dstY, dstWidth, dstHeight,
- false);
- }
- return true;
- }
-
- /**
- * Draws an image to the GdkGraphics context, at (x,y) scaled to
- * width and height, with optional compositing with a background color.
- */
- public boolean drawImage (GdkGraphics g, int x, int y, int width, int height,
- Color bgcolor, ImageObserver observer)
- {
- if (addObserver(observer))
- return false;
-
- if ( this.width <= 0 || this.height <= 0 )
- return true;
-
- synchronized(GdkPixbufDecoder.pixbufLock)
- {
- if(bgcolor != null)
- drawPixelsScaled(g, bgcolor.getRed (), bgcolor.getGreen (),
- bgcolor.getBlue (), x, y, width, height, true);
- else
- drawPixelsScaled(g, 0, 0, 0, x, y, width, height, false);
- }
-
- return true;
- }
// Private methods ////////////////////////////////////////////////
diff --git a/gnu/java/awt/peer/gtk/GtkToolkit.java b/gnu/java/awt/peer/gtk/GtkToolkit.java
index 7757db0c5..163fc52f7 100644
--- a/gnu/java/awt/peer/gtk/GtkToolkit.java
+++ b/gnu/java/awt/peer/gtk/GtkToolkit.java
@@ -78,37 +78,17 @@ import javax.imageio.spi.IIORegistry;
this class. If getPeer() ever goes away, we can implement a hash table
that will keep up with every window's peer, but for now this is faster. */
-/**
- * This class accesses a system property called
- * <tt>gnu.java.awt.peer.gtk.Graphics</tt>. If the property is defined and
- * equal to "Graphics2D", the cairo-based GdkGraphics2D will be used in
- * drawing contexts. Any other value will cause the older GdkGraphics
- * object to be used.
- */
public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
{
Hashtable containers = new Hashtable();
static EventQueue q;
- static boolean useGraphics2dSet;
- static boolean useGraphics2d;
static Thread mainThread;
- public static boolean useGraphics2D()
- {
- if (useGraphics2dSet)
- return useGraphics2d;
- useGraphics2d = System.getProperty("gnu.java.awt.peer.gtk.Graphics",
- "Graphics").equals("Graphics2D");
- useGraphics2dSet = true;
- return useGraphics2d;
- }
-
static native void gtkInit(int portableNativeSync);
static
{
- if (Configuration.INIT_LOAD_LIBRARY)
- System.loadLibrary("gtkpeer");
+ System.loadLibrary("gtkpeer");
int portableNativeSync;
String portNatSyncProp =
@@ -179,10 +159,7 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
Image image;
try
{
- if (useGraphics2D())
- image = GdkPixbufDecoder.createBufferedImage(filename);
- else
- image = new GtkImage(filename);
+ image = CairoSurface.getBufferedImage( new GtkImage( filename ) );
}
catch (IllegalArgumentException iae)
{
@@ -196,10 +173,7 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
Image image;
try
{
- if (useGraphics2D())
- image = GdkPixbufDecoder.createBufferedImage(url);
- else
- image = new GtkImage(url);
+ image = CairoSurface.getBufferedImage( new GtkImage( url ) );
}
catch (IllegalArgumentException iae)
{
@@ -210,13 +184,13 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
public Image createImage (ImageProducer producer)
{
+ if (producer == null)
+ return null;
+
Image image;
try
{
- if (useGraphics2D())
- image = GdkPixbufDecoder.createBufferedImage(producer);
- else
- image = new GtkImage(producer);
+ image = CairoSurface.getBufferedImage( new GtkImage( producer ) );
}
catch (IllegalArgumentException iae)
{
@@ -231,16 +205,9 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
Image image;
try
{
- if (useGraphics2D())
- image = GdkPixbufDecoder.createBufferedImage(imagedata,
- imageoffset,
- imagelength);
- else
- {
- byte[] datacopy = new byte[imagelength];
- System.arraycopy(imagedata, imageoffset, datacopy, 0, imagelength);
- return new GtkImage(datacopy);
- }
+ byte[] data = new byte[ imagelength ];
+ System.arraycopy(imagedata, imageoffset, data, 0, imagelength);
+ image = CairoSurface.getBufferedImage( new GtkImage( data ) );
}
catch (IllegalArgumentException iae)
{
@@ -257,7 +224,7 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
*/
public ImageProducer createImageProducer(URL url)
{
- return new GdkPixbufDecoder(url);
+ return createImage( url ).getSource();
}
/**
diff --git a/gnu/java/awt/peer/gtk/GtkVolatileImage.java b/gnu/java/awt/peer/gtk/GtkVolatileImage.java
index 496090a09..cebb715ab 100644
--- a/gnu/java/awt/peer/gtk/GtkVolatileImage.java
+++ b/gnu/java/awt/peer/gtk/GtkVolatileImage.java
@@ -1,4 +1,4 @@
-/* GtkVolatileImage.java -- a hardware-accelerated image buffer
+/* GtkVolatileImage.java -- wraps an X pixmap
Copyright (C) 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,6 +38,7 @@ exception statement from your version. */
package gnu.java.awt.peer.gtk;
import java.awt.ImageCapabilities;
+import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.image.BufferedImage;
@@ -46,54 +47,96 @@ import java.awt.image.VolatileImage;
public class GtkVolatileImage extends VolatileImage
{
- private int width;
- private int height;
+ int width, height;
private ImageCapabilities caps;
- public GtkVolatileImage(int width, int height)
- {
- this(width, height, null);
- }
+ /**
+ * Don't touch, accessed from native code.
+ */
+ private long nativePointer;
- public GtkVolatileImage(int width, int height, ImageCapabilities caps)
+ /**
+ * Offscreen image we draw to.
+ */
+ CairoSurface offScreen;
+
+ private boolean needsUpdate = false;
+
+ native long init(GtkComponentPeer component, int width, int height);
+
+ native void destroy();
+
+ native int[] getPixels();
+
+ native void update(GtkImage image);
+
+ public GtkVolatileImage(GtkComponentPeer component,
+ int width, int height, ImageCapabilities caps)
{
this.width = width;
this.height = height;
this.caps = caps;
+ nativePointer = init( component, width, height );
+ offScreen = new CairoSurface( width, height );
}
- // FIXME: should return a buffered image snapshot of the accelerated
- // visual
- public BufferedImage getSnapshot()
+ public GtkVolatileImage(int width, int height, ImageCapabilities caps)
{
- return null;
+ this(null, width, height, caps);
}
- public int getWidth()
+ public GtkVolatileImage(int width, int height)
{
- return width;
+ this(null, width, height, null);
}
- public int getHeight()
+ public void finalize()
{
- return height;
+ dispose();
+ }
+
+ public void dispose()
+ {
+ destroy();
+ }
+
+ void invalidate()
+ {
+ needsUpdate = true;
+ }
+
+ public BufferedImage getSnapshot()
+ {
+ CairoSurface cs = new CairoSurface( width, height );
+ cs.setPixels( getPixels() );
+ return CairoSurface.getBufferedImage( cs );
+ }
+
+ public Graphics getGraphics()
+ {
+ return createGraphics();
}
- // FIXME: should return a graphics wrapper around this image's
- // visual
public Graphics2D createGraphics()
{
- return null;
+ invalidate();
+ return offScreen.getGraphics();
}
public int validate(GraphicsConfiguration gc)
{
+ if( needsUpdate )
+ {
+ update( offScreen.getGtkImage() );
+ needsUpdate = false;
+ return VolatileImage.IMAGE_RESTORED;
+ }
return VolatileImage.IMAGE_OK;
}
public boolean contentsLost()
{
- return false;
+ return needsUpdate;
}
public ImageCapabilities getCapabilities()
@@ -101,18 +144,28 @@ public class GtkVolatileImage extends VolatileImage
return caps;
}
- public synchronized Object getProperty (String name, ImageObserver observer)
+ public int getWidth()
+ {
+ return width;
+ }
+
+ public int getHeight()
{
- return null;
+ return height;
}
- public synchronized int getWidth (ImageObserver observer)
+ public int getWidth(java.awt.image.ImageObserver observer)
{
return width;
}
- public synchronized int getHeight (ImageObserver observer)
+ public int getHeight(java.awt.image.ImageObserver observer)
{
return height;
}
+
+ public Object getProperty(String name, ImageObserver observer)
+ {
+ return null;
+ }
}
diff --git a/gnu/java/awt/peer/gtk/VolatileImageGraphics.java b/gnu/java/awt/peer/gtk/VolatileImageGraphics.java
new file mode 100644
index 000000000..81de3d705
--- /dev/null
+++ b/gnu/java/awt/peer/gtk/VolatileImageGraphics.java
@@ -0,0 +1,129 @@
+/* VolatileImageGraphics.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.java.awt.peer.gtk;
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.font.GlyphVector;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferInt;
+import java.awt.image.ColorModel;
+import java.awt.image.DirectColorModel;
+import java.awt.image.RenderedImage;
+import java.awt.image.ImageObserver;
+import java.util.WeakHashMap;
+
+public class VolatileImageGraphics extends CairoSurfaceGraphics
+{
+ private GtkVolatileImage owner;
+
+ public VolatileImageGraphics(GtkVolatileImage owner)
+ {
+ super( owner.offScreen );
+ this.owner = owner;
+ }
+
+ VolatileImageGraphics(VolatileImageGraphics copyFrom)
+ {
+ super( copyFrom.owner.offScreen );
+ owner = copyFrom.owner;
+ }
+
+ /**
+ * Abstract methods.
+ */
+ public Graphics create()
+ {
+ return new VolatileImageGraphics( this );
+ }
+
+ public void copyAreaImpl(int x, int y, int width, int height, int dx, int dy)
+ {
+ surface.copyAreaNative(x, y, width, height, dx, dy, surface.width);
+ owner.invalidate();
+ }
+
+ /**
+ * Overloaded methods that do actual drawing need to enter the gdk threads
+ * and also do certain things before and after.
+ */
+ public void draw(Shape s)
+ {
+ super.draw(s);
+ Rectangle r = s.getBounds();
+ owner.invalidate();
+ }
+
+ public void fill(Shape s)
+ {
+ super.fill(s);
+ Rectangle r = s.getBounds();
+ owner.invalidate();
+ }
+
+ public void drawRenderedImage(RenderedImage image, AffineTransform xform)
+ {
+ super.drawRenderedImage(image, xform);
+ owner.invalidate();
+ }
+
+ protected boolean drawImage(Image img, AffineTransform xform,
+ Color bgcolor, ImageObserver obs)
+ {
+ boolean rv = super.drawImage(img, xform, bgcolor, obs);
+ owner.invalidate();
+ return rv;
+ }
+
+ public void drawGlyphVector(GlyphVector gv, float x, float y)
+ {
+ super.drawGlyphVector(gv, x, y);
+ owner.invalidate();
+ }
+}
+
diff --git a/gnu/java/awt/peer/swing/SwingComponent.java b/gnu/java/awt/peer/swing/SwingComponent.java
index 04ca7294f..a51b758ad 100644
--- a/gnu/java/awt/peer/swing/SwingComponent.java
+++ b/gnu/java/awt/peer/swing/SwingComponent.java
@@ -62,7 +62,7 @@ public interface SwingComponent
/**
* Handles a mouse event. This is usually forwarded to
- * {@link Component#processMouseMotionEvent(MouseEvent)} of the swing
+ * {@link java.awt.Component#processMouseMotionEvent(MouseEvent)} of the swing
* component.
*
* @param ev the mouse event
@@ -71,7 +71,7 @@ public interface SwingComponent
/**
* Handles a mouse motion event. This is usually forwarded to
- * {@link Component#processMouseEvent(MouseEvent)} of the swing
+ * {@link java.awt.Component#processMouseEvent(MouseEvent)} of the swing
* component.
*
* @param ev the mouse motion event
@@ -80,7 +80,7 @@ public interface SwingComponent
/**
* Handles a key event. This is usually forwarded to
- * {@link Component#processKeyEvent(KeyEvent)} of the swing
+ * {@link java.awt.Component#processKeyEvent(KeyEvent)} of the swing
* component.
*
* @param ev the key event
diff --git a/gnu/java/awt/peer/swing/SwingComponentPeer.java b/gnu/java/awt/peer/swing/SwingComponentPeer.java
index 5d484e021..f60c8e96c 100644
--- a/gnu/java/awt/peer/swing/SwingComponentPeer.java
+++ b/gnu/java/awt/peer/swing/SwingComponentPeer.java
@@ -48,6 +48,8 @@ import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
@@ -98,8 +100,9 @@ public class SwingComponentPeer
/**
* Creates a SwingComponentPeer instance. Subclasses are expected to call
- * this constructor and thereafter call {@link #init(Component, JComponent)}
- * in order to setup the AWT and Swing components properly.
+ * this constructor and thereafter call
+ * {@link #init(Component, SwingComponent)} in order to setup the AWT and
+ * Swing components properly.
*/
protected SwingComponentPeer()
{
@@ -164,9 +167,12 @@ public class SwingComponentPeer
*/
public Image createImage(int width, int height)
{
- Component parent = awtComponent.getParent();
- ComponentPeer parentPeer = parent.getPeer();
- return parentPeer.createImage(width, height);
+ GraphicsEnvironment graphicsEnv =
+ GraphicsEnvironment.getLocalGraphicsEnvironment();
+ GraphicsDevice dev = graphicsEnv.getDefaultScreenDevice();
+ GraphicsConfiguration conf = dev.getDefaultConfiguration();
+ Image image = conf.createCompatibleImage(width, height);
+ return image;
}
/**
@@ -442,20 +448,6 @@ public class SwingComponentPeer
return retVal;
}
- /**
- * Prepares an image for rendering on this component. This is called by
- * {@link Component#prepareImage(Image, int, int, ImageObserver)}.
- *
- * @param img the image to prepare
- * @param width the desired width of the rendered image
- * @param height the desired height of the rendered image
- * @param ob the image observer to be notified of updates in the preparation
- * process
- *
- * @return <code>true</code> if the image has been fully prepared,
- * <code>false</code> otherwise (in which case the image observer
- * receives updates)
- */
public void paint(Graphics graphics)
{
// FIXME: I don't know what this method is supposed to do.
@@ -478,8 +470,17 @@ public class SwingComponentPeer
public boolean prepareImage(Image img, int width, int height, ImageObserver ob)
{
Component parent = awtComponent.getParent();
- ComponentPeer parentPeer = parent.getPeer();
- return parentPeer.prepareImage(img, width, height, ob);
+ boolean res;
+ if(parent != null)
+ {
+ ComponentPeer parentPeer = parent.getPeer();
+ res = parentPeer.prepareImage(img, width, height, ob);
+ }
+ else
+ {
+ res = Toolkit.getDefaultToolkit().prepareImage(img, width, height, ob);
+ }
+ return res;
}
public void print(Graphics graphics)
diff --git a/gnu/java/awt/peer/swing/SwingContainerPeer.java b/gnu/java/awt/peer/swing/SwingContainerPeer.java
index 0b2fb992f..f433e1b5c 100644
--- a/gnu/java/awt/peer/swing/SwingContainerPeer.java
+++ b/gnu/java/awt/peer/swing/SwingContainerPeer.java
@@ -92,7 +92,12 @@ public class SwingContainerPeer
*/
public Insets getInsets()
{
- return insets();
+ Insets retVal;
+ if (swingComponent != null)
+ retVal = swingComponent.getJComponent().getInsets();
+ else
+ retVal = new Insets(0, 0, 0, 0);
+ return retVal;
}
/**
@@ -209,6 +214,8 @@ public class SwingContainerPeer
protected void handleMouseEvent(MouseEvent ev)
{
Component comp = awtComponent.getComponentAt(ev.getPoint());
+ if(comp == null)
+ comp = awtComponent;
if (comp != null)
{
ComponentPeer peer = comp.getPeer();
diff --git a/gnu/java/awt/peer/swing/SwingFramePeer.java b/gnu/java/awt/peer/swing/SwingFramePeer.java
index fea1b504a..0d5a02d78 100644
--- a/gnu/java/awt/peer/swing/SwingFramePeer.java
+++ b/gnu/java/awt/peer/swing/SwingFramePeer.java
@@ -53,9 +53,9 @@ import java.awt.peer.FramePeer;
* As a minimum, a subclass must implement all the remaining abstract methods
* as well as the following methods:
* <ul>
- * <li>{@link ComponentPeer#getLocationOnScreen()}</li>
- * <li>{@link ComponentPeer#getGraphics()}</li>
- * <li>{@link ComponentPeer#createImage(int, int)}</li>
+ * <li>{@link java.awt.peer.ComponentPeer#getLocationOnScreen()}</li>
+ * <li>{@link java.awt.peer.ComponentPeer#getGraphics()}</li>
+ * <li>{@link java.awt.peer.ComponentPeer#createImage(int, int)}</li>
* </ul>
*
* @author Roman Kennke (kennke@aicas.com)
diff --git a/gnu/java/awt/peer/swing/SwingMenuBarPeer.java b/gnu/java/awt/peer/swing/SwingMenuBarPeer.java
index bd9dcd77a..0033efb02 100644
--- a/gnu/java/awt/peer/swing/SwingMenuBarPeer.java
+++ b/gnu/java/awt/peer/swing/SwingMenuBarPeer.java
@@ -174,7 +174,7 @@ public class SwingMenuBarPeer
/**
* Adds a help menu to the menu bar.
*
- * @param m the menu to add
+ * @param menu the menu to add
*/
public void addHelpMenu(Menu menu)
{
diff --git a/gnu/java/awt/peer/swing/SwingTextFieldPeer.java b/gnu/java/awt/peer/swing/SwingTextFieldPeer.java
index a4c6d82d2..0c3b4e726 100644
--- a/gnu/java/awt/peer/swing/SwingTextFieldPeer.java
+++ b/gnu/java/awt/peer/swing/SwingTextFieldPeer.java
@@ -283,7 +283,7 @@ public class SwingTextFieldPeer
* @param startPos the start index of the selection
* @param endPos the start index of the selection
*/
- public void select(int start_pos, int endPos)
+ public void select(int startPos, int endPos)
{
// TODO: Must be implemented.
}
diff --git a/gnu/java/awt/peer/swing/SwingWindowPeer.java b/gnu/java/awt/peer/swing/SwingWindowPeer.java
index 2f89795ca..43a509b95 100644
--- a/gnu/java/awt/peer/swing/SwingWindowPeer.java
+++ b/gnu/java/awt/peer/swing/SwingWindowPeer.java
@@ -48,9 +48,9 @@ import java.awt.peer.WindowPeer;
* As a minimum, a subclass must implement all the remaining abstract methods
* as well as the following methods:
* <ul>
- * <li>{@link ComponentPeer#getLocationOnScreen()}</li>
- * <li>{@link ComponentPeer#getGraphics()}</li>
- * <li>{@link ComponentPeer#createImage(int, int)}</li>
+ * <li>{@link java.awt.peer.ComponentPeer#getLocationOnScreen()}</li>
+ * <li>{@link java.awt.peer.ComponentPeer#getGraphics()}</li>
+ * <li>{@link java.awt.peer.ComponentPeer#createImage(int, int)}</li>
* </ul>
*
* @author Roman Kennke (kennke@aicas.com)
diff --git a/gnu/java/awt/print/JavaPrinterGraphics.java b/gnu/java/awt/print/JavaPrinterGraphics.java
new file mode 100644
index 000000000..9a3db0125
--- /dev/null
+++ b/gnu/java/awt/print/JavaPrinterGraphics.java
@@ -0,0 +1,518 @@
+/* JavaPrinterGraphics.java -- AWT printer rendering 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 gnu.java.awt.print;
+
+import gnu.java.awt.peer.gtk.CairoSurface;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.image.ImageObserver;
+import java.awt.image.PixelGrabber;
+import java.awt.print.PageFormat;
+import java.awt.print.Pageable;
+import java.awt.print.Paper;
+import java.awt.print.Printable;
+import java.awt.print.PrinterException;
+import java.awt.print.PrinterGraphics;
+import java.awt.print.PrinterJob;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.text.AttributedCharacterIterator;
+
+/**
+ * Graphics context to draw to PostScript.
+ *
+ * @author Sven de Marothy
+ */
+public class JavaPrinterGraphics extends Graphics implements PrinterGraphics
+{
+
+ /**
+ * The used graphics context.
+ */
+ private Graphics g;
+
+ /**
+ * The associated printer job.
+ */
+ private PrinterJob printerJob;
+
+ /**
+ * Rendering resolution
+ */
+ private static final double DPI = 72.0;
+
+ /**
+ * Rendered image size.
+ */
+ private int xSize, ySize;
+
+ /**
+ * The image to render to.
+ */
+ private Image image;
+
+ public JavaPrinterGraphics( PrinterJob printerJob )
+ {
+ this.printerJob = printerJob;
+ }
+
+ /**
+ * Spool a document to PostScript.
+ * If Pageable is non-null, it will print that, otherwise it will use
+ * the supplied printable and pageFormat.
+ */
+ public SpooledDocument spoolPostScript(Printable printable,
+ PageFormat pageFormat,
+ Pageable pageable)
+ throws PrinterException
+ {
+ try
+ {
+ // spool to a temporary file
+ File temp = File.createTempFile("cpspool", ".ps");
+ temp.deleteOnExit();
+
+ PrintWriter out = new PrintWriter
+ (new BufferedWriter
+ (new OutputStreamWriter
+ (new FileOutputStream(temp), "ISO8859_1"), 1000000));
+
+ writePSHeader(out);
+
+ if(pageable != null)
+ {
+ for(int index = 0; index < pageable.getNumberOfPages(); index++)
+ spoolPage(out, pageable.getPrintable(index),
+ pageable.getPageFormat(index), index);
+ }
+ else
+ {
+ int index = 0;
+ while(spoolPage(out, printable, pageFormat, index++) ==
+ Printable.PAGE_EXISTS);
+ }
+ out.println("%%Trailer");
+ out.println("%%EOF");
+ out.close();
+ return new SpooledDocument( temp );
+ }
+ catch (IOException e)
+ {
+ PrinterException pe = new PrinterException();
+ pe.initCause(e);
+ throw pe;
+ }
+ }
+
+ /**
+ * Spools a single page, returns NO_SUCH_PAGE unsuccessful,
+ * PAGE_EXISTS if it was.
+ */
+ public int spoolPage(PrintWriter out,
+ Printable printable,
+ PageFormat pageFormat,
+ int index) throws IOException, PrinterException
+ {
+ initImage( pageFormat );
+ if(printable.print(this, pageFormat, index) == Printable.NO_SUCH_PAGE)
+ return Printable.NO_SUCH_PAGE;
+ g.dispose();
+ g = null;
+ writePage( out, pageFormat );
+ return Printable.PAGE_EXISTS;
+ }
+
+ private void initImage(PageFormat pageFormat)
+ {
+ // Create a really big image and draw to that.
+ xSize = (int)(DPI*pageFormat.getWidth()/72.0);
+ ySize = (int)(DPI*pageFormat.getHeight()/72.0);
+
+ // Swap X and Y sizes if it's a Landscape page.
+ if( pageFormat.getOrientation() != PageFormat.PORTRAIT )
+ {
+ int t = xSize;
+ xSize = ySize;
+ ySize = t;
+ }
+
+ // FIXME: This should at least be BufferedImage.
+ // Fix once we have a working B.I.
+ // Graphics2D should also be supported of course.
+ image = CairoSurface.getBufferedImage(xSize, ySize);
+
+ g = image.getGraphics();
+ setColor(Color.white);
+ fillRect(0, 0, xSize, ySize);
+ setColor(Color.black);
+ }
+
+ private void writePSHeader(PrintWriter out)
+ {
+ out.println("%!PS-Adobe-3.0");
+ out.println("%%Title: "+printerJob.getJobName());
+ out.println("%%Creator: GNU Classpath ");
+ out.println("%%DocumentData: Clean8Bit");
+
+ out.println("%%DocumentNeededResources: font Times-Roman Helvetica Courier");
+ // out.println("%%Pages: "+); // FIXME # pages.
+ out.println("%%EndComments");
+
+ out.println("%%BeginProlog");
+ out.println("%%EndProlog");
+ out.println("%%BeginSetup");
+
+ // FIXME: Paper name
+ // E.g. "A4" "Letter"
+ // out.println("%%BeginFeature: *PageSize A4");
+
+ out.println("%%EndFeature");
+
+ out.println("%%EndSetup");
+
+ // out.println("%%Page: 1 1");
+ }
+
+ private void writePage(PrintWriter out, PageFormat pageFormat)
+ {
+ out.println("%%BeginPageSetup");
+
+ Paper p = pageFormat.getPaper();
+ double pWidth = p.getWidth();
+ double pHeight = p.getHeight();
+
+ if( pageFormat.getOrientation() == PageFormat.PORTRAIT )
+ out.println( "%%Orientation: Portrait" );
+ else
+ {
+ out.println( "%%Orientation: Landscape" );
+ double t = pWidth;
+ pWidth = pHeight;
+ pHeight = t;
+ }
+
+ out.println("gsave % first save");
+
+ // 595x842; 612x792 respectively
+ out.println("<< /PageSize [" +pWidth + " "+pHeight+ "] >> setpagedevice");
+
+ // invert the Y axis so that we get screen-like coordinates instead.
+ AffineTransform pageTransform = new AffineTransform();
+ if( pageFormat.getOrientation() == PageFormat.REVERSE_LANDSCAPE )
+ {
+ pageTransform.translate(pWidth, pHeight);
+ pageTransform.scale(-1.0, -1.0);
+ }
+ concatCTM(out, pageTransform);
+ out.println("%%EndPageSetup");
+
+ out.println("gsave");
+
+
+ // Draw the image
+ out.println(xSize+" "+ySize+" 8 [1 0 0 -1 0 "+ySize+" ]");
+ out.println("{currentfile 3 string readhexstring pop} bind");
+ out.println("false 3 colorimage");
+ int[] pixels = new int[xSize * ySize];
+ PixelGrabber pg = new PixelGrabber(image, 0, 0, xSize, ySize, pixels, 0, xSize);
+
+ try {
+ pg.grabPixels();
+ } catch (InterruptedException e) {
+ out.println("% Bug getting pixels!");
+ }
+
+ int n = 0;
+ for (int j = 0; j < ySize; j++) {
+ for (int i = 0; i < xSize; i++) {
+ out.print( colorTripleHex(pixels[j * xSize + i]) );
+ if(((++n)%11) == 0) out.println();
+ }
+ }
+
+ out.println();
+ out.println("%%EOF");
+ out.println("grestore");
+ out.println("showpage");
+ }
+
+ /**
+ * Get a nonsperated hex RGB triple, e.g. FFFFFF = white
+ */
+ private String colorTripleHex(int num){
+ String s = "";
+
+ try {
+ s = Integer.toHexString( ( num & 0x00FFFFFF ) );
+ if( s.length() < 6 )
+ {
+ s = "000000"+s;
+ return s.substring(s.length()-6);
+ }
+ } catch (Exception e){
+ s = "FFFFFF";
+ }
+
+ return s;
+ }
+
+ private void concatCTM(PrintWriter out, AffineTransform Tx){
+ double[] matrixElements = new double[6];
+ Tx.getMatrix(matrixElements);
+
+ out.print("[ ");
+ for(int i=0;i<6;i++)
+ out.print(matrixElements[i]+" ");
+ out.println("] concat");
+ }
+
+ //-----------------------------------------------------------------------------
+ /**
+ * PrinterGraphics method - Returns the printer job associated with this object.
+ */
+ public PrinterJob getPrinterJob()
+ {
+ return printerJob;
+ }
+
+ /**
+ * The rest of the methods here are just pass-throughs to g.
+ */
+ public void clearRect(int x, int y, int width, int height)
+ {
+ g.clearRect(x, y, width, height);
+ }
+
+ public void clipRect(int x, int y, int width, int height)
+ {
+ g.clipRect(x, y, width, height);
+ }
+
+ public void copyArea(int x, int y, int width, int height, int dx, int dy)
+ {
+ g.copyArea(x, y, width, height, dx, dy);
+ }
+
+ public Graphics create()
+ {
+ return g.create();
+ }
+
+ public void dispose()
+ {
+ }
+
+ public void drawArc(int x, int y, int width, int height, int startAngle,
+ int arcAngle)
+ {
+ g.drawArc(x, y, width, height, startAngle, arcAngle);
+ }
+
+ public boolean drawImage(Image img, int x, int y, Color bgcolor,
+ ImageObserver observer)
+ {
+ return g.drawImage(img, x, y, bgcolor, observer);
+ }
+
+ public boolean drawImage(Image img, int x, int y, ImageObserver observer)
+ {
+ return g.drawImage(img, x, y, observer);
+ }
+
+ public boolean drawImage(Image img, int x, int y, int width, int height,
+ Color bgcolor, ImageObserver observer)
+ {
+ return g.drawImage(img, x, y, width, height, bgcolor, observer);
+ }
+
+ public boolean drawImage(Image img, int x, int y, int width, int height,
+ ImageObserver observer)
+ {
+ return g.drawImage(img, x, y, width, height, observer);
+ }
+
+ public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2,
+ int sx1, int sy1, int sx2, int sy2, Color bgcolor,
+ ImageObserver observer)
+ {
+ return g.drawImage(img, dx1, dy1, dx2, dy2,
+ sx1, sy1, sx2, sy2, bgcolor, observer);
+ }
+
+ public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2,
+ int sx1, int sy1, int sx2, int sy2, ImageObserver observer)
+ {
+ return g.drawImage(img, dx1, dy1, dx2, dy2,
+ sx1, sy1, sx2, sy2, observer);
+ }
+
+ public void drawLine(int x1, int y1, int x2, int y2)
+ {
+ g.drawLine(x1, y1, x2, y2);
+ }
+
+ public void drawOval(int x, int y, int width, int height)
+ {
+ g.drawOval(x, y, width, height);
+ }
+
+ public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
+ {
+ g.drawPolygon(xPoints, yPoints, nPoints);
+ }
+
+ public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints)
+ {
+ g.drawPolyline(xPoints, yPoints, nPoints);
+ }
+
+ public void drawRoundRect(int x, int y, int width, int height,
+ int arcWidth, int arcHeight)
+ {
+ g.drawRoundRect(x, y, width, height, arcWidth, arcHeight);
+ }
+
+ public void drawString(AttributedCharacterIterator iterator, int x, int y)
+ {
+ g.drawString(iterator, x, y);
+ }
+
+ public void drawString(String str, int x, int y)
+ {
+ g.drawString(str, x, y);
+ }
+
+ public void fillArc(int x, int y, int width, int height,
+ int startAngle, int arcAngle)
+ {
+ g.fillArc(x, y, width, height, startAngle, arcAngle);
+ }
+
+ public void fillOval(int x, int y, int width, int height)
+ {
+ g.fillOval(x, y, width, height);
+ }
+
+ public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints)
+ {
+ g.fillPolygon(xPoints, yPoints, nPoints);
+ }
+
+ public void fillRect(int x, int y, int width, int height)
+ {
+ g.fillRect(x, y, width, height);
+ }
+
+ public void fillRoundRect(int x, int y, int width, int height,
+ int arcWidth, int arcHeight)
+ {
+ g.fillRoundRect(x, y, width, height, arcWidth, arcHeight);
+ }
+
+ public Shape getClip()
+ {
+ return g.getClip();
+ }
+
+ public Rectangle getClipBounds()
+ {
+ return g.getClipBounds();
+ }
+
+ public Color getColor()
+ {
+ return g.getColor();
+ }
+
+ public Font getFont()
+ {
+ return g.getFont();
+ }
+
+ public FontMetrics getFontMetrics(Font f)
+ {
+ return g.getFontMetrics(f);
+ }
+
+ public void setClip(int x, int y, int width, int height)
+ {
+ g.setClip(x, y, width, height);
+ }
+
+ public void setClip(Shape clip)
+ {
+ g.setClip(clip);
+ }
+
+ public void setColor(Color c)
+ {
+ g.setColor(c);
+ }
+
+ public void setFont(Font font)
+ {
+ g.setFont(font);
+ }
+
+ public void setPaintMode()
+ {
+ g.setPaintMode();
+ }
+
+ public void setXORMode(Color c1)
+ {
+ g.setXORMode(c1);
+ }
+
+ public void translate(int x, int y)
+ {
+ g.translate(x, y);
+ }
+}
+
diff --git a/gnu/java/awt/print/JavaPrinterJob.java b/gnu/java/awt/print/JavaPrinterJob.java
new file mode 100644
index 000000000..adeeba04a
--- /dev/null
+++ b/gnu/java/awt/print/JavaPrinterJob.java
@@ -0,0 +1,403 @@
+/* JavaPrinterJob.java -- AWT printing implemented on javax.print.
+ 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.java.awt.print;
+
+import java.awt.HeadlessException;
+import java.awt.print.PageFormat;
+import java.awt.print.Pageable;
+import java.awt.print.Printable;
+import java.awt.print.PrinterException;
+import java.awt.print.PrinterJob;
+import java.util.Locale;
+
+import javax.print.CancelablePrintJob;
+import javax.print.DocFlavor;
+import javax.print.DocPrintJob;
+import javax.print.PrintException;
+import javax.print.PrintService;
+import javax.print.PrintServiceLookup;
+import javax.print.ServiceUI;
+import javax.print.attribute.HashPrintRequestAttributeSet;
+import javax.print.attribute.IntegerSyntax;
+import javax.print.attribute.PrintRequestAttributeSet;
+import javax.print.attribute.TextSyntax;
+import javax.print.attribute.standard.Copies;
+import javax.print.attribute.standard.JobName;
+import javax.print.attribute.standard.OrientationRequested;
+import javax.print.attribute.standard.RequestingUserName;
+
+/**
+ * This is the default implementation of PrinterJob
+ *
+ * @author Sven de Marothy
+ */
+public class JavaPrinterJob extends PrinterJob
+{
+ /**
+ * The print service associated with this job
+ */
+ private PrintService printer = null;
+
+ /**
+ * Printing options;
+ */
+ private PrintRequestAttributeSet attributes;
+
+ /**
+ * Available print services
+ */
+ private static PrintService[] services;
+
+ /**
+ * The actual print job.
+ */
+ private DocPrintJob printJob;
+
+ /**
+ * The Printable object to print.
+ */
+ private Printable printable;
+
+ /**
+ * Page format.
+ */
+ private PageFormat pageFormat;
+
+ /**
+ * A pageable, or null
+ */
+ private Pageable pageable = null;
+
+ /**
+ * Cancelled or not
+ */
+ private boolean cancelled = false;
+
+ static
+ {
+ // lookup all services without any constraints
+ services = PrintServiceLookup.lookupPrintServices
+ (DocFlavor.INPUT_STREAM.POSTSCRIPT, null);
+ }
+
+ private static final Class copyClass = (new Copies(1)).getClass();
+ private static final Class jobNameClass = (new JobName("", null)).getClass();
+ private static final Class userNameClass = (new RequestingUserName("", null)).getClass();
+
+ /**
+ * Initializes a new instance of <code>PrinterJob</code>.
+ */
+ public JavaPrinterJob()
+ {
+ attributes = new HashPrintRequestAttributeSet();
+ setCopies(1);
+ setJobName("Java Printing");
+ pageFormat = new PageFormat(); // default page format.
+ }
+
+ private void getPageAttributes()
+ {
+ OrientationRequested orientation = (OrientationRequested)
+ attributes.get( OrientationRequested.LANDSCAPE.getCategory() );
+ if( orientation == null)
+ return;
+
+ if( orientation.equals(OrientationRequested.PORTRAIT) )
+ pageFormat.setOrientation(PageFormat.PORTRAIT);
+ else if( orientation.equals(OrientationRequested.LANDSCAPE) )
+ pageFormat.setOrientation(PageFormat.LANDSCAPE);
+ else if( orientation.equals(OrientationRequested.REVERSE_LANDSCAPE) )
+ pageFormat.setOrientation(PageFormat.REVERSE_LANDSCAPE);
+ }
+
+ /**
+ * Returns the number of copies to be printed.
+ *
+ * @return The number of copies to be printed.
+ */
+ public int getCopies()
+ {
+ return ((IntegerSyntax)attributes.get( jobNameClass )).getValue();
+ }
+
+ /**
+ * Sets the number of copies to be printed.
+ *
+ * @param copies The number of copies to be printed.
+ */
+ public void setCopies(int copies)
+ {
+ attributes.add( new Copies( copies ) );
+ }
+
+ /**
+ * Returns the name of the print job.
+ *
+ * @return The name of the print job.
+ */
+ public String getJobName()
+ {
+ return ((TextSyntax)attributes.get( jobNameClass )).getValue();
+ }
+
+ /**
+ * Sets the name of the print job.
+ *
+ * @param job_name The name of the print job.
+ */
+ public void setJobName(String job_name)
+ {
+ attributes.add( new JobName(job_name, Locale.getDefault()) );
+ }
+
+ /**
+ * Returns the printing user name.
+ *
+ * @return The printing username.
+ */
+ public String getUserName()
+ {
+ return ((TextSyntax)attributes.get( userNameClass )).getValue();
+ }
+
+ /**
+ * Cancels an in progress print job.
+ */
+ public void cancel()
+ {
+ try
+ {
+ if(printJob != null && (printJob instanceof CancelablePrintJob))
+ {
+ ((CancelablePrintJob)printJob).cancel();
+ cancelled = true;
+ }
+ }
+ catch(PrintException pe)
+ {
+ }
+ }
+
+ /**
+ * Tests whether or not this job has been cancelled.
+ *
+ * @return <code>true</code> if this job has been cancelled, <code>false</code>
+ * otherwise.
+ */
+ public boolean isCancelled()
+ {
+ return cancelled;
+ }
+
+ /**
+ * Clones the specified <code>PageFormat</code> object then alters the
+ * clone so that it represents the default page format.
+ *
+ * @param page_format The <code>PageFormat</code> to clone.
+ *
+ * @return A new default page format.
+ */
+ public PageFormat defaultPage(PageFormat page_format)
+ {
+ return new PageFormat();
+ }
+
+ /**
+ * Displays a dialog box to the user which allows the page format
+ * attributes to be modified.
+ *
+ * @param page_format The <code>PageFormat</code> object to modify.
+ *
+ * @return The modified <code>PageFormat</code>.
+ */
+ public PageFormat pageDialog(PageFormat page_format)
+ throws HeadlessException
+ {
+ return defaultPage(null);
+ }
+
+ /**
+ * Prints the pages.
+ */
+ public void print() throws PrinterException
+ {
+ if( printable == null && pageable == null ) // nothing to print?
+ return;
+
+ PostScriptGraphics2D pg = new PostScriptGraphics2D( this );
+ SpooledDocument doc = pg.spoolPostScript( printable, pageFormat,
+ pageable );
+
+ cancelled = false;
+ printJob = printer.createPrintJob();
+ try
+ {
+ printJob.print(doc, attributes);
+ }
+ catch (PrintException pe)
+ {
+ PrinterException p = new PrinterException();
+ p.initCause(pe);
+ throw p;
+ }
+ // no printjob active.
+ printJob = null;
+ }
+
+ /**
+ * Prints the page with given attributes.
+ */
+ public void print (PrintRequestAttributeSet attributes)
+ throws PrinterException
+ {
+ this.attributes = attributes;
+ print();
+ }
+
+ /**
+ * Displays a dialog box to the user which allows the print job
+ * attributes to be modified.
+ *
+ * @return <code>false</code> if the user cancels the dialog box,
+ * <code>true</code> otherwise.
+ */
+ public boolean printDialog() throws HeadlessException
+ {
+ return printDialog( attributes );
+ }
+
+ /**
+ * Displays a dialog box to the user which allows the print job
+ * attributes to be modified.
+ *
+ * @return <code>false</code> if the user cancels the dialog box,
+ * <code>true</code> otherwise.
+ */
+ public boolean printDialog(PrintRequestAttributeSet attributes)
+ throws HeadlessException
+ {
+ PrintService chosenPrinter = ServiceUI.printDialog
+ (null, 50, 50, services, null,
+ DocFlavor.INPUT_STREAM.POSTSCRIPT, attributes);
+
+ getPageAttributes();
+
+ if( chosenPrinter != null )
+ {
+ try
+ {
+ setPrintService( chosenPrinter );
+ }
+ catch(PrinterException pe)
+ {
+ // Should not happen.
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * This sets the pages that are to be printed.
+ *
+ * @param pageable The pages to be printed, which may not be <code>null</code>.
+ */
+ public void setPageable(Pageable pageable)
+ {
+ if( pageable == null )
+ throw new NullPointerException("Pageable cannot be null.");
+ this.pageable = pageable;
+ }
+
+ /**
+ * Sets this specified <code>Printable</code> as the one to use for
+ * rendering the pages on the print device.
+ *
+ * @param printable The <code>Printable</code> for the print job.
+ */
+ public void setPrintable(Printable printable)
+ {
+ this.printable = printable;
+ }
+
+ /**
+ * Sets the <code>Printable</code> and the page format for the pages
+ * to be printed.
+ *
+ * @param printable The <code>Printable</code> for the print job.
+ * @param page_format The <code>PageFormat</code> for the print job.
+ */
+ public void setPrintable(Printable printable, PageFormat page_format)
+ {
+ this.printable = printable;
+ this.pageFormat = page_format;
+ }
+
+ /**
+ * Makes any alterations to the specified <code>PageFormat</code>
+ * necessary to make it work with the current printer. The alterations
+ * are made to a clone of the input object, which is then returned.
+ *
+ * @param page_format The <code>PageFormat</code> to validate.
+ *
+ * @return The validated <code>PageFormat</code>.
+ */
+ public PageFormat validatePage(PageFormat page_format)
+ {
+ // FIXME
+ return page_format;
+ }
+
+ /**
+ * Change the printer for this print job to service. Subclasses that
+ * support setting the print service override this method. Throws
+ * PrinterException when the class doesn't support setting the printer,
+ * the service doesn't support Pageable or Printable interfaces for 2D
+ * print output.
+ * @param service The new printer to use.
+ * @throws PrinterException if service is not valid.
+ */
+ public void setPrintService(PrintService service)
+ throws PrinterException
+ {
+ if(!service.isDocFlavorSupported(DocFlavor.INPUT_STREAM.POSTSCRIPT))
+ throw new PrinterException("This printer service is not supported.");
+ printer = service;
+ }
+}
diff --git a/gnu/java/awt/print/PostScriptGraphics2D.java b/gnu/java/awt/print/PostScriptGraphics2D.java
new file mode 100644
index 000000000..2303f44b7
--- /dev/null
+++ b/gnu/java/awt/print/PostScriptGraphics2D.java
@@ -0,0 +1,1349 @@
+/* PostScriptGraphics2D.java -- AWT printer rendering 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 gnu.java.awt.print;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.Paint;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.GradientPaint;
+import java.awt.Graphics;
+import java.awt.GraphicsConfiguration;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Polygon;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.Stroke;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Arc2D;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.RoundRectangle2D;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.font.TextLayout;
+import java.awt.image.BufferedImage;
+import java.awt.image.BufferedImageOp;
+import java.awt.image.renderable.RenderableImage;
+import java.awt.image.RenderedImage;
+import java.awt.image.ImageObserver;
+import java.awt.image.PixelGrabber;
+import java.awt.print.PageFormat;
+import java.awt.print.Pageable;
+import java.awt.print.Paper;
+import java.awt.print.Printable;
+import java.awt.print.PrinterException;
+import java.awt.print.PrinterGraphics;
+import java.awt.print.PrinterJob;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.text.AttributedCharacterIterator;
+import java.util.Map;
+
+/**
+ * Class PostScriptGraphics2D - Class that implements the Graphics2D object,
+ * writing the output to a PostScript or EPS file
+ *
+ * @author Sven de Marothy
+ *
+ */
+class PostScriptGraphics2D extends Graphics2D
+{
+ /**
+ * The associated printer job.
+ */
+ private PrinterJob printerJob;
+
+ /**
+ * Output file.
+ */
+ private PrintWriter out;
+
+ // Graphics data
+ private AffineTransform currentTransform = new AffineTransform();
+ private AffineTransform pageTransform;
+ private RenderingHints renderingHints;
+ private Paint currentPaint = null;
+ private Shape clipShape = null;
+ private Font currentFont = null;
+ private Color currentColor = Color.black;
+ private Color backgroundColor = Color.white;
+ private Stroke currentStroke = null;
+ private static Stroke ordinaryStroke = new BasicStroke(0.0f,
+ BasicStroke.CAP_BUTT,
+ BasicStroke.JOIN_MITER);
+ private float cx; // current drawing position
+ private float cy; // current drawing position
+ private boolean currentFontIsPS; // set if currentFont is one of the above
+
+ // settings
+ private double pageX = 595;
+ private double pageY = 842;
+ private double Y = pageY;
+ private boolean gradientOn = false;
+
+ /**
+ * Constructor
+ *
+ */
+ public PostScriptGraphics2D( PrinterJob pg )
+ {
+ printerJob = pg;
+ // create transform objects
+ pageTransform = new AffineTransform();
+ currentTransform = new AffineTransform();
+
+ /*
+ Create Rendering hints
+ No text aliasing
+ Quality color and rendering
+ Bicubic interpolation
+ Fractional metrics supported
+ */
+ renderingHints = new RenderingHints(null);
+ renderingHints.put(RenderingHints.KEY_RENDERING,
+ RenderingHints.VALUE_RENDER_QUALITY);
+ renderingHints.put(RenderingHints.KEY_TEXT_ANTIALIASING,
+ RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
+ renderingHints.put(RenderingHints.KEY_INTERPOLATION,
+ RenderingHints.VALUE_INTERPOLATION_BICUBIC);
+ renderingHints.put(RenderingHints.KEY_FRACTIONALMETRICS,
+ RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+ renderingHints.put(RenderingHints.KEY_COLOR_RENDERING,
+ RenderingHints.VALUE_COLOR_RENDER_QUALITY);
+ }
+
+ /**
+ * Spool a document to PostScript.
+ * If Pageable is non-null, it will print that, otherwise it will use
+ * the supplied printable and pageFormat.
+ */
+ public SpooledDocument spoolPostScript(Printable printable,
+ PageFormat pageFormat,
+ Pageable pageable)
+ throws PrinterException
+ {
+ try
+ {
+ // spool to a temporary file
+ File temp = File.createTempFile("cpspool", ".ps");
+ temp.deleteOnExit();
+
+ out = new PrintWriter(new BufferedWriter
+ (new OutputStreamWriter
+ (new FileOutputStream(temp),
+ "ISO8859_1"), 1000000));
+
+ writePSHeader();
+
+ if(pageable != null)
+ {
+ for(int index = 0; index < pageable.getNumberOfPages(); index++)
+ spoolPage(out, pageable.getPrintable(index),
+ pageable.getPageFormat(index), index);
+ }
+ else
+ {
+ int index = 0;
+ while(spoolPage(out, printable, pageFormat, index++) ==
+ Printable.PAGE_EXISTS);
+ }
+ out.println("%%Trailer");
+ out.println("%%EOF");
+ out.close();
+ return new SpooledDocument( temp );
+ }
+ catch (IOException e)
+ {
+ PrinterException pe = new PrinterException();
+ pe.initCause(e);
+ throw pe;
+ }
+ }
+
+ //--------------------------------------------------------------------------
+
+ /**
+ * Write the postscript file header,
+ * setup the page format and transforms.
+ */
+ private void writePSHeader()
+ {
+ out.println("%!PS-Adobe-3.0");
+ out.println("%%Title: "+printerJob.getJobName());
+ out.println("%%Creator: GNU Classpath ");
+ out.println("%%DocumentData: Clean8Bit");
+
+ out.println("%%DocumentNeededResources: font Times-Roman Helvetica Courier");
+ out.println("%%EndComments");
+
+ out.println("%%BeginProlog");
+ out.println("%%EndProlog");
+ out.println("%%BeginSetup");
+
+ out.println("%%EndFeature");
+ setupFonts();
+ out.println("%%EndSetup");
+
+ // set default fonts and colors
+ setFont( new Font("Dialog", Font.PLAIN, 12) );
+ currentColor = Color.white;
+ currentStroke = new BasicStroke();
+ setPaint(currentColor);
+ setStroke(currentStroke);
+ }
+
+ /**
+ * setupFonts - set up the font dictionaries for
+ * helvetica, times and courier
+ */
+ private void setupFonts()
+ {
+ out.println("/helveticaISO");
+ out.println("/Helvetica findfont dup length dict begin");
+ out.println("{ 1 index /FID eq { pop pop } { def } ifelse } forall");
+ out.println("/Encoding ISOLatin1Encoding def");
+ out.println("currentdict end definefont pop");
+
+ out.println("/timesISO");
+ out.println("/Times-Roman findfont dup length dict begin");
+ out.println("{ 1 index /FID eq { pop pop } { def } ifelse } forall");
+ out.println("/Encoding ISOLatin1Encoding def");
+ out.println("currentdict end definefont pop");
+
+ out.println("/courierISO");
+ out.println("/Courier findfont dup length dict begin");
+ out.println("{ 1 index /FID eq { pop pop } { def } ifelse } forall");
+ out.println("/Encoding ISOLatin1Encoding def");
+ out.println("currentdict end definefont pop");
+ }
+
+ /**
+ * Spools a single page, returns NO_SUCH_PAGE unsuccessful,
+ * PAGE_EXISTS if it was.
+ */
+ public int spoolPage(PrintWriter out,
+ Printable printable,
+ PageFormat pageFormat,
+ int index) throws IOException, PrinterException
+ {
+ out.println("%%BeginPageSetup");
+
+ Paper p = pageFormat.getPaper();
+ pageX = p.getWidth();
+ pageY = p.getHeight();
+
+ if( pageFormat.getOrientation() == PageFormat.PORTRAIT )
+ out.println( "%%Orientation: Portrait" );
+ else
+ {
+ out.println( "%%Orientation: Landscape" );
+ double t = pageX;
+ pageX = pageY;
+ pageY = t;
+ }
+
+ setClip(0, 0, (int)pageX, (int)pageY);
+
+ out.println("gsave % first save");
+
+ // 595x842; 612x792 respectively
+ out.println("<< /PageSize [" +pageX + " "+pageY+ "] >> setpagedevice");
+
+ if( pageFormat.getOrientation() != PageFormat.LANDSCAPE )
+ {
+ pageTransform.translate(pageX, 0);
+ pageTransform.scale(-1.0, 1.0);
+ }
+
+ // save the original CTM
+ pushCTM();
+ concatCTM(pageTransform);
+ setTransform(new AffineTransform());
+
+ out.println("%%EndPageSetup");
+
+ out.println("gsave");
+
+ if( printable.print(this, pageFormat, index) == Printable.NO_SUCH_PAGE )
+ return Printable.NO_SUCH_PAGE;
+
+ out.println("grestore");
+ out.println("showpage");
+
+ return Printable.PAGE_EXISTS;
+ }
+
+ /** push the Current Transformation Matrix onto the PS stack */
+ private void pushCTM()
+ {
+ out.println("matrix currentmatrix % pushCTM()");
+ }
+
+ /** pop the Current Transformation Matrix from the PS stack */
+ private void popCTM()
+ {
+ out.println("setmatrix % restore CTM");
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ public Graphics create()
+ {
+ return null;
+ }
+
+ public void drawOval(int x, int y, int width, int height)
+ {
+ out.println("% drawOval()");
+ setStroke(ordinaryStroke);
+ draw(new Ellipse2D.Double(x, y, width, height));
+ setStroke(currentStroke);
+ }
+
+ public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints)
+ {
+ if (nPoints <= 0 || xPoints.length < nPoints || yPoints.length < nPoints)
+ return;
+ out.println("newpath % drawPolyLine()");
+ out.println(xPoints[0] + " " + yPoints[0] + " moveto");
+ for (int i = 1; i < nPoints; i++)
+ out.println(xPoints[i] + " " + yPoints[i] + " lineto");
+ out.println("closepath");
+ out.println("stroke");
+ }
+
+ public void drawRoundRect(int x, int y, int width, int height, int arcWidth,
+ int arcHeight)
+ {
+ out.println("% drawRoundRect()");
+ RoundRectangle2D.Double rr = new RoundRectangle2D.Double(x, y, width,
+ height, arcWidth,
+ arcHeight);
+ setStroke(ordinaryStroke);
+ draw(rr);
+ setStroke(currentStroke);
+ }
+
+ public void fillRoundRect(int x, int y, int width, int height, int arcWidth,
+ int arcHeight)
+ {
+ out.println("% fillRoundRect()");
+ RoundRectangle2D.Double rr = new RoundRectangle2D.Double(x, y, width,
+ height, arcWidth,
+ arcHeight);
+ fill(rr);
+ }
+
+ public void drawArc(int x, int y, int width, int height, int startAngle,
+ int arcAngle)
+ {
+ setStroke(ordinaryStroke);
+ draw(new Arc2D.Double(x, y, width, height, startAngle, arcAngle, Arc2D.OPEN));
+ setStroke(currentStroke);
+ }
+
+ public void fillArc(int x, int y, int width, int height, int startAngle,
+ int arcAngle)
+ {
+ fill(new Arc2D.Double(x, y, width, height, startAngle, arcAngle, Arc2D.PIE));
+ }
+
+ public void fillOval(int x, int y, int width, int height)
+ {
+ out.println("% fillOval()");
+ fill( new Ellipse2D.Double(x, y, width, height) );
+ }
+
+ public void fillPolygon(int[] x, int[] y, int nPoints)
+ {
+ out.println("% fillPolygon()");
+ fill( new Polygon(x, y, nPoints) );
+ }
+
+ public void drawLine(int x1, int y1, int x2, int y2)
+ {
+ out.println("% drawLine()");
+ setStroke(ordinaryStroke);
+ out.println("newpath");
+ out.println(x1 + " " + (y1) + " moveto");
+ out.println(x2 + " " + (y2) + " lineto");
+ out.println("stroke");
+ setStroke(currentStroke);
+ }
+
+ //--------------- Image drawing ------------------------------------------
+ public boolean drawImage(Image img, int x, int y, Color bgcolor,
+ ImageObserver observer)
+ {
+ int w = img.getWidth(null);
+ int h = img.getHeight(null);
+
+ return drawImage(img, x, y, x + w, y + h, 0, 0, w - 1, h - 1, bgcolor,
+ observer);
+ }
+
+ public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2,
+ int sx1, int sy1, int sx2, int sy2, Color bgcolor,
+ ImageObserver observer)
+ {
+ int n = 0;
+ boolean flipx = false;
+ boolean flipy = false;
+
+ // swap X and Y's
+ if (sx1 > sx2)
+ {
+ n = sx1;
+ sx1 = sx2;
+ sx2 = n;
+ flipx = ! flipx;
+ }
+ if (sy1 > sy2)
+ {
+ n = sy1;
+ sy1 = sy2;
+ sy2 = n;
+ flipy = ! flipy;
+ }
+ if (dx1 > dx2)
+ {
+ n = dx1;
+ dx1 = dx2;
+ dx2 = n;
+ flipx = ! flipx;
+ }
+ if (dy1 > dy2)
+ {
+ n = dy1;
+ dy1 = dy2;
+ dy2 = n;
+ flipy = ! flipy;
+ }
+ n = 0;
+ int sw = sx2 - sx1; // source width
+ int sh = sy2 - sy1; // source height
+ int[] pixels = new int[sw * sh]; // pixel buffer
+ int dw = dx2 - dx1; // destination width
+ int dh = dy2 - dy1; // destination height
+ double x_scale = ((double) dw) / ((double) sw);
+ double y_scale = ((double) dh) / ((double) sh);
+
+ out.println("% drawImage() 2");
+ out.println("gsave");
+ out.println(dx1 + " " + dy1 + " translate");
+ out.println(dw + " " + dh + " scale");
+ out.println(sw + " " + sh + " 8 [" + (flipx ? -sw : sw) + " 0 0 "
+ + (flipy ? -sh : sh) + " " + (flipx ? sw : 0) + " "
+ + (flipy ? sh : 0) + " ]");
+ out.println("{currentfile 3 string readhexstring pop} bind");
+ out.println("false 3 colorimage");
+
+ PixelGrabber pg = new PixelGrabber(img, sx1, sy1, sw, sh, pixels, 0, sw);
+ try
+ {
+ pg.grabPixels();
+ }
+ catch (InterruptedException e)
+ {
+ System.err.println("interrupted waiting for pixels!");
+ return (false);
+ }
+
+ if ((pg.getStatus() & ImageObserver.ABORT) != 0)
+ {
+ System.err.println("image fetch aborted or errored");
+ return (false);
+ }
+
+ for (int j = 0; j < sh; j++)
+ {
+ for (int i = 0; i < sw; i++)
+ {
+ out.print(colorTripleHex(new Color(pixels[j * sw + i])));
+ if (((++n) % 11) == 0)
+ out.println();
+ }
+ }
+
+ out.println();
+ out.println("%%EOF");
+ out.println("grestore");
+ return true;
+ }
+
+ public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2,
+ int sx1, int sy1, int sx2, int sy2,
+ ImageObserver observer)
+ {
+ return drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null,
+ observer);
+ }
+
+ public boolean drawImage(Image img, int x, int y, ImageObserver observer)
+ {
+ return drawImage(img, x, y, null, observer);
+ }
+
+ public boolean drawImage(Image img, int x, int y, int width, int height,
+ Color bgcolor, ImageObserver observer)
+ {
+ int sw = img.getWidth(null);
+ int sh = img.getHeight(null);
+ return drawImage(img, x, y, x + width, y + height, /* destination */
+ 0, 0, sw - 1, sh - 1, /* source */
+ bgcolor, observer);
+ // correct?
+ }
+
+ public boolean drawImage(Image img, int x, int y, int width, int height,
+ ImageObserver observer)
+ {
+ return drawImage(img, x, y, width, height, null, observer);
+ }
+
+ /** Renders a BufferedImage that is filtered with a BufferedImageOp. */
+ public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y)
+ {
+ BufferedImage result = op.filter(img, null);
+ drawImage(result, x, y, null);
+ }
+
+ /** Renders an image, applying a transform from image space
+ into user space before drawing. */
+ public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs)
+ {
+ AffineTransform oldTransform = new AffineTransform(currentTransform);
+ boolean ret;
+
+ transform(xform);
+ ret = drawImage(img, 0, 0, null, obs);
+ setTransform(oldTransform);
+
+ return ret;
+ }
+
+ /** Renders a RenderableImage, applying a transform from image
+ space into user space before drawing. */
+ public void drawRenderableImage(RenderableImage img, AffineTransform xform)
+ {
+ // FIXME
+ }
+
+ /** Renders a RenderedImage, applying a transform from
+ image space into user space before drawing. */
+ public void drawRenderedImage(RenderedImage img, AffineTransform xform)
+ {
+ // FIXME
+ }
+
+ //-------------------------------------------------------------------------
+ public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
+ {
+ setStroke(ordinaryStroke);
+ draw(new Polygon(xPoints, yPoints, nPoints));
+ setStroke(currentStroke);
+ }
+
+ public void drawString(String str, int x, int y)
+ {
+ drawString(str, (float) x, (float) y);
+ }
+
+ public void drawString(String str, float x, float y)
+ {
+ if( str.trim().equals("") )
+ return; // don't draw whitespace, silly!
+
+ if( currentFontIsPS )
+ {
+ drawStringPSFont(str, x, y);
+ return;
+ }
+
+ TextLayout text = new TextLayout(str, currentFont, getFontRenderContext());
+ Shape s = text.getOutline(AffineTransform.getTranslateInstance(x, y));
+ drawStringShape(s);
+ }
+
+ private void drawStringPSFont(String str, float x, float y)
+ {
+ out.println("% drawString PS font");
+ out.println(x + " " + y + " moveto");
+ saveAndInvertAxis();
+ out.println("(" + str + ") show");
+ restoreAxis();
+ }
+
+ private void saveAndInvertAxis()
+ {
+ // Invert the Y axis of the CTM.
+ popCTM();
+ pushCTM();
+
+ double[] test =
+ {
+ pageTransform.getScaleX(), pageTransform.getShearY(),
+ pageTransform.getShearX(), pageTransform.getScaleY(),
+ pageTransform.getTranslateX(),
+ -pageTransform.getTranslateY() + pageY
+ };
+
+ double[] test2 =
+ {
+ currentTransform.getScaleX(),
+ currentTransform.getShearY(),
+ -currentTransform.getShearX(),
+ -currentTransform.getScaleY(),
+ currentTransform.getTranslateX(),
+ currentTransform.getTranslateY()
+ };
+
+ AffineTransform total = new AffineTransform(test);
+ total.concatenate(new AffineTransform(test2));
+ concatCTM(total);
+ }
+
+ private void restoreAxis()
+ {
+ // reset the CTM
+ popCTM();
+ pushCTM();
+ AffineTransform total = new AffineTransform(pageTransform);
+ total.concatenate(currentTransform);
+ concatCTM(total);
+ }
+
+ /**
+ * special drawing routine for string shapes,
+ * which need to be drawn with the Y axis uninverted.
+ */
+ private void drawStringShape(Shape s)
+ {
+ saveAndInvertAxis();
+
+ // draw the shape s with an inverted Y axis.
+ PathIterator pi = s.getPathIterator(new AffineTransform());
+ float[] coords = new float[6];
+
+ while (! pi.isDone())
+ {
+ switch (pi.currentSegment(coords))
+ {
+ case PathIterator.SEG_MOVETO:
+ out.println((coords[0]) + " " + (Y - coords[1]) + " moveto");
+ cx = coords[0];
+ cy = coords[1];
+ break;
+ case PathIterator.SEG_LINETO:
+ out.println((coords[0]) + " " + (Y - coords[1]) + " lineto");
+ cx = coords[0];
+ cy = coords[1];
+ break;
+ case PathIterator.SEG_QUADTO:
+ // convert to cubic bezier points
+ float x1 = (cx + 2 * coords[0]) / 3;
+ float y1 = (cy + 2 * coords[1]) / 3;
+ float x2 = (2 * coords[2] + coords[0]) / 3;
+ float y2 = (2 * coords[3] + coords[1]) / 3;
+
+ out.print((x1) + " " + (Y - y1) + " ");
+ out.print((x2) + " " + (Y - y2) + " ");
+ out.println((coords[2]) + " " + (Y - coords[3]) + " curveto");
+ cx = coords[2];
+ cy = coords[3];
+ break;
+ case PathIterator.SEG_CUBICTO:
+ out.print((coords[0]) + " " + (Y - coords[1]) + " ");
+ out.print((coords[2]) + " " + (Y - coords[3]) + " ");
+ out.println((coords[4]) + " " + (Y - coords[5]) + " curveto");
+ cx = coords[4];
+ cy = coords[5];
+ break;
+ case PathIterator.SEG_CLOSE:
+ out.println("closepath");
+ break;
+ }
+ pi.next();
+ }
+ out.println("fill");
+
+ restoreAxis();
+ }
+
+ public void setColor(Color c)
+ {
+ /* don't set the color if it's already set */
+ if (c.equals(currentColor))
+ return;
+ gradientOn = false;
+ currentColor = c;
+ currentPaint = c; // Graphics2D extends colors to paint
+
+ out.println(colorTriple(c) + " setrgbcolor");
+ }
+
+ public void clearRect(int x, int y, int width, int height)
+ {
+ out.println("% clearRect");
+ Color c = currentColor;
+ setColor(backgroundColor);
+ fill(new Rectangle2D.Double(x, y, width, height));
+ setColor(c);
+ }
+
+ public void clipRect(int x, int y, int width, int height)
+ {
+ clip(new Rectangle2D.Double(x, y, width, height));
+ }
+
+ public void copyArea(int x, int y, int width, int height, int dx, int dy)
+ {
+ // FIXME
+ }
+
+ public void fillRect(int x, int y, int width, int height)
+ {
+ fill(new Rectangle2D.Double(x, y, width, height));
+ }
+
+ public void dispose()
+ {
+ }
+
+ public void setClip(int x, int y, int width, int height)
+ {
+ out.println("% setClip()");
+ setClip(new Rectangle2D.Double(x, y, width, height));
+ }
+
+ public void setClip(Shape s)
+ {
+ clip(s);
+ }
+
+ public Shape getClip()
+ {
+ return clipShape;
+ }
+
+ public Rectangle getClipBounds()
+ {
+ return clipShape.getBounds();
+ }
+
+ public Color getColor()
+ {
+ return currentColor;
+ }
+
+ public Font getFont()
+ {
+ return currentFont;
+ }
+
+ public FontMetrics getFontMetrics()
+ {
+ return getFontMetrics(currentFont);
+ }
+
+ public FontMetrics getFontMetrics(Font f)
+ {
+ // FIXME
+ return null;
+ }
+
+ public void setFont(Font font)
+ {
+ out.println("% setfont()");
+ if (font == null)
+ // use the default font
+ font = new Font("Dialog", Font.PLAIN, 12);
+ currentFont = font;
+ setPSFont(); // set up the PostScript fonts
+ }
+
+ /**
+ * Setup the postscript font if the current font is one
+ */
+ private void setPSFont()
+ {
+ currentFontIsPS = false;
+
+ String s = currentFont.getName();
+ out.println("% setPSFont: Fontname: " + s);
+ if (s.equalsIgnoreCase("Helvetica") || s.equalsIgnoreCase("SansSerif"))
+ out.print("/helveticaISO findfont ");
+ else if (s.equalsIgnoreCase("Times New Roman"))
+ out.print("/timesISO findfont ");
+ else if (s.equalsIgnoreCase("Courier"))
+ out.print("/courierISO findfont ");
+ else
+ return;
+
+ currentFontIsPS = true;
+
+ out.print(currentFont.getSize() + " scalefont ");
+ out.println("setfont");
+ }
+
+ /** XOR mode is not supported */
+ public void setPaintMode()
+ {
+ }
+
+ /** XOR mode is not supported */
+ public void setXORMode(Color c1)
+ {
+ }
+
+ public void close()
+ {
+ out.println("showpage");
+ out.println("%%Trailer");
+ out.println("grestore % restore original stuff");
+ out.println("%%EOF");
+
+ try
+ {
+ out.close();
+ }
+ catch (Exception e)
+ {
+ }
+ out = null;
+ }
+
+ //----------------------------------------------------------------
+ // Graphics2D stuff ----------------------------------------------
+
+ /** Sets the values of an arbitrary number of
+ preferences for the rendering algorithms. */
+ public void addRenderingHints(Map hints)
+ {
+ /* rendering hint changes are disallowed */
+ }
+
+ /** write a shape to the file */
+ private void writeShape(Shape s)
+ {
+ PathIterator pi = s.getPathIterator(new AffineTransform());
+ float[] coords = new float[6];
+
+ while (! pi.isDone())
+ {
+ switch (pi.currentSegment(coords))
+ {
+ case PathIterator.SEG_MOVETO:
+ out.println(coords[0] + " " + (coords[1]) + " moveto");
+ cx = coords[0];
+ cy = coords[1];
+ break;
+ case PathIterator.SEG_LINETO:
+ out.println(coords[0] + " " + (coords[1]) + " lineto");
+ cx = coords[0];
+ cy = coords[1];
+ break;
+ case PathIterator.SEG_QUADTO:
+ // convert to cubic bezier points
+ float x1 = (cx + 2 * coords[0]) / 3;
+ float y1 = (cy + 2 * coords[1]) / 3;
+ float x2 = (2 * coords[2] + coords[0]) / 3;
+ float y2 = (2 * coords[3] + coords[1]) / 3;
+
+ out.print(x1 + " " + (Y - y1) + " ");
+ out.print(x2 + " " + (Y - y2) + " ");
+ out.println(coords[2] + " " + (Y - coords[3]) + " curveto");
+ cx = coords[2];
+ cy = coords[3];
+ break;
+ case PathIterator.SEG_CUBICTO:
+ out.print(coords[0] + " " + coords[1] + " ");
+ out.print(coords[2] + " " + coords[3] + " ");
+ out.println(coords[4] + " " + coords[5] + " curveto");
+ cx = coords[4];
+ cy = coords[5];
+ break;
+ case PathIterator.SEG_CLOSE:
+ out.println("closepath");
+ break;
+ }
+ pi.next();
+ }
+ }
+
+ /** Intersects the current Clip with the interior of
+ the specified Shape and sets the Clip to the resulting intersection. */
+ public void clip(Shape s)
+ {
+ clipShape = s;
+ out.println("% clip INACTIVE");
+ // writeShape(s);
+ // out.println("clip");
+ }
+
+ /** Strokes the outline of a Shape using the
+ settings of the current Graphics2D context.*/
+ public void draw(Shape s)
+ {
+ if(!(currentStroke instanceof BasicStroke))
+ fill(currentStroke.createStrokedShape(s));
+
+ out.println("% draw");
+ writeShape(s);
+ out.println("stroke");
+ }
+
+ /** Renders the text of the specified GlyphVector using the
+ Graphics2D context's rendering attributes. */
+ public void drawGlyphVector(GlyphVector gv, float x, float y)
+ {
+ out.println("% drawGlyphVector");
+ Shape s = gv.getOutline();
+ drawStringShape(AffineTransform.getTranslateInstance(x, y)
+ .createTransformedShape(s));
+ }
+
+ /** Renders the text of the specified iterator,
+ using the Graphics2D context's current Paint.*/
+ public void drawString(AttributedCharacterIterator iterator, float x, float y)
+ {
+ TextLayout text = new TextLayout(iterator, getFontRenderContext());
+ Shape s = text.getOutline(AffineTransform.getTranslateInstance(x, y));
+ drawStringShape(s);
+ }
+
+ /** Renders the text of the specified iterator,
+ using the Graphics2D context's current Paint. */
+ public void drawString(AttributedCharacterIterator iterator, int x, int y)
+ {
+ drawString(iterator, (float) x, (float) y);
+ }
+
+ /** Fills the interior of a Shape using the settings of the Graphics2D context. */
+ public void fill(Shape s)
+ {
+ out.println("% fill");
+ if (! gradientOn)
+ {
+ writeShape(s);
+ out.println("fill");
+ }
+ else
+ {
+ out.println("gsave");
+ writeShape(s);
+ out.println("clip");
+ writeGradient();
+ out.println("shfill");
+ out.println("grestore");
+ }
+ }
+
+ /** Returns the background color used for clearing a region. */
+ public Color getBackground()
+ {
+ return backgroundColor;
+ }
+
+ /** Returns the current Composite in the Graphics2D context. */
+ public Composite getComposite()
+ {
+ // FIXME
+ return null;
+ }
+
+ /** Returns the device configuration associated with this Graphics2D. */
+ public GraphicsConfiguration getDeviceConfiguration()
+ {
+ // FIXME
+ out.println("% getDeviceConfiguration()");
+ return null;
+ }
+
+ /** Get the rendering context of the Font within this Graphics2D context. */
+ public FontRenderContext getFontRenderContext()
+ {
+ out.println("% getFontRenderContext()");
+
+ double[] scaling =
+ {
+ pageTransform.getScaleX(), 0, 0,
+ -pageTransform.getScaleY(), 0, 0
+ };
+
+ return (new FontRenderContext(new AffineTransform(scaling), false, true));
+ }
+
+ /** Returns the current Paint of the Graphics2D context. */
+ public Paint getPaint()
+ {
+ return currentPaint;
+ }
+
+ /** Returns the value of a single preference for the rendering algorithms. */
+ public Object getRenderingHint(RenderingHints.Key hintKey)
+ {
+ return renderingHints.get(hintKey);
+ }
+
+ /** Gets the preferences for the rendering algorithms. */
+ public RenderingHints getRenderingHints()
+ {
+ return renderingHints;
+ }
+
+ /** Returns the current Stroke in the Graphics2D context. */
+ public Stroke getStroke()
+ {
+ return currentStroke;
+ }
+
+ /** Returns a copy of the current Transform in the Graphics2D context. */
+ public AffineTransform getTransform()
+ {
+ return currentTransform;
+ }
+
+ /**
+ * Checks whether or not the specified Shape intersects
+ * the specified Rectangle, which is in device space.
+ */
+ public boolean hit(Rectangle rect, Shape s, boolean onStroke)
+ {
+ Rectangle2D.Double r = new Rectangle2D.Double(rect.getX(), rect.getY(),
+ rect.getWidth(),
+ rect.getHeight());
+ return s.intersects(r);
+ }
+
+ /** Sets the background color for the Graphics2D context.*/
+ public void setBackground(Color color)
+ {
+ out.println("% setBackground(" + color + ")");
+ backgroundColor = color;
+ }
+
+ /** Sets the Composite for the Graphics2D context.
+ Not supported. */
+ public void setComposite(Composite comp)
+ {
+ }
+
+ /** Sets the Paint attribute for the Graphics2D context.*/
+ public void setPaint(Paint paint)
+ {
+ currentPaint = paint;
+ gradientOn = false;
+ if (paint instanceof Color)
+ {
+ setColor((Color) paint);
+ return;
+ }
+ if (paint instanceof GradientPaint)
+ {
+ gradientOn = true;
+ return;
+ }
+ }
+
+ /* get a space seperated 0.0 - 1.0 color RGB triple */
+ private String colorTriple(Color c)
+ {
+ return (((double) c.getRed() / 255.0) + " "
+ + ((double) c.getGreen() / 255.0) + " "
+ + ((double) c.getBlue() / 255.0));
+ }
+
+ /**
+ * Get a nonsperated hex RGB triple, eg FFFFFF = white
+ * used by writeGradient and drawImage
+ */
+ private String colorTripleHex(Color c)
+ {
+ String r = "00" + Integer.toHexString(c.getRed());
+ r = r.substring(r.length() - 2);
+ String g = "00" + Integer.toHexString(c.getGreen());
+ g = g.substring(g.length() - 2);
+ String b = "00" + Integer.toHexString(c.getBlue());
+ b = b.substring(b.length() - 2);
+ return r + g + b;
+ }
+
+ /* write the current gradient fill */
+ private void writeGradient()
+ {
+ GradientPaint paint = (GradientPaint) currentPaint;
+ out.println("% writeGradient()");
+
+ int n = 1;
+ double x;
+ double y;
+ double dx;
+ double dy;
+ Point2D p1 = currentTransform.transform(paint.getPoint1(), null);
+ Point2D p2 = currentTransform.transform(paint.getPoint2(), null);
+ x = p1.getX();
+ y = p1.getY();
+ dx = p2.getX() - x;
+ dy = p2.getY() - y;
+
+ // get number of repetitions
+ while (x + n * dx < pageY && y + n * dy < pageX && x + n * dx > 0
+ && y + n * dy > 0)
+ n++;
+
+ out.println("<<"); // start
+ out.println("/ShadingType 2"); // gradient fill
+ out.println("/ColorSpace [ /DeviceRGB ]"); // RGB colors
+ out.print("/Coords [");
+ out.print(x + " " + y + " " + (x + n * dx) + " " + (y + n * dy) + " ");
+ out.println("]"); // coordinates defining the axis
+ out.println("/Function <<");
+ out.println("/FunctionType 0");
+ out.println("/Order 1");
+ out.println("/Domain [ 0 1 ]");
+ out.println("/Range [ 0 1 0 1 0 1 ]");
+ out.println("/BitsPerSample 8");
+ out.println("/Size [ " + (1 + n) + " ]");
+ out.print("/DataSource < " + colorTripleHex(paint.getColor1()) + " "
+ + colorTripleHex(paint.getColor2()) + " ");
+ for (; n > 1; n--)
+ if (paint.isCyclic())
+ {
+ if ((n % 2) == 1)
+ out.print(colorTripleHex(paint.getColor1()) + " ");
+ else
+ out.print(colorTripleHex(paint.getColor2()) + " ");
+ }
+ else
+ out.print(colorTripleHex(paint.getColor2()) + " ");
+ out.println(">");
+ out.println(">>");
+ out.println(">>");
+ }
+
+ /** Sets the value of a single preference for the rendering algorithms. */
+ public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue)
+ {
+ /* we don't allow the changing of rendering hints. */
+ }
+
+ /** Replaces the values of all preferences for the rendering algorithms
+ with the specified hints. */
+ public void setRenderingHints(Map hints)
+ {
+ /* we don't allow the changing of rendering hints. */
+ }
+
+ /**
+ * Sets the Stroke for the Graphics2D context. BasicStroke fully implemented.
+ */
+ public void setStroke(Stroke s)
+ {
+ currentStroke = s;
+
+ if (! (s instanceof BasicStroke))
+ return;
+
+ BasicStroke bs = (BasicStroke) s;
+ out.println("% setStroke()");
+ try
+ {
+ // set the line width
+ out.println(bs.getLineWidth() + " setlinewidth");
+
+ // set the line dash
+ float[] dashArray = bs.getDashArray();
+ if (dashArray != null)
+ {
+ out.print("[ ");
+ for (int i = 0; i < dashArray.length; i++)
+ out.print(dashArray[i] + " ");
+ out.println("] " + bs.getDashPhase() + " setdash");
+ }
+ else
+ out.println("[] 0 setdash"); // set solid
+
+ // set the line cap
+ switch (bs.getEndCap())
+ {
+ case BasicStroke.CAP_BUTT:
+ out.println("0 setlinecap");
+ break;
+ case BasicStroke.CAP_ROUND:
+ out.println("1 setlinecap");
+ break;
+ case BasicStroke.CAP_SQUARE:
+ out.println("2 setlinecap");
+ break;
+ }
+
+ // set the line join
+ switch (bs.getLineJoin())
+ {
+ case BasicStroke.JOIN_BEVEL:
+ out.println("2 setlinejoin");
+ break;
+ case BasicStroke.JOIN_MITER:
+ out.println("0 setlinejoin");
+ out.println(bs.getMiterLimit() + " setmiterlimit");
+ break;
+ case BasicStroke.JOIN_ROUND:
+ out.println("1 setlinejoin");
+ break;
+ }
+ }
+ catch (Exception e)
+ {
+ out.println("% Exception in setStroke()");
+ }
+ }
+
+ //////////////////// TRANSFORM SETTING /////////////////////////////////////
+ private void concatCTM(AffineTransform Tx)
+ {
+ double[] matrixElements = new double[6];
+ Tx.getMatrix(matrixElements);
+
+ out.print("[ ");
+ for (int i = 0; i < 6; i++)
+ out.print(matrixElements[i] + " ");
+ out.println("] concat");
+ }
+
+ /** Sets the Transform in the Graphics2D context. */
+ public void setTransform(AffineTransform Tx)
+ {
+ // set the transformation matrix;
+ currentTransform = Tx;
+
+ // concatenate the current transform and the page transform
+ AffineTransform totalTransform = new AffineTransform(pageTransform);
+ totalTransform.concatenate(currentTransform);
+ out.println("% setTransform()");
+ out.println("% pageTransform:" + pageTransform);
+ out.println("% currentTransform:" + currentTransform);
+ out.println("% totalTransform:" + totalTransform);
+
+ popCTM();
+ pushCTM(); // set the CTM to it's original state
+ concatCTM(totalTransform); // apply our transforms
+ }
+
+ /** Composes an AffineTransform object with the Transform
+ in this Graphics2D according to the rule last-specified-first-applied. */
+ public void transform(AffineTransform Tx)
+ {
+ // concatenate the current transform
+ currentTransform.concatenate(Tx);
+ // and the PS CTM
+ concatCTM(Tx);
+ }
+
+ ////////////////////////// TRANSFORMS //////////////////////////////////////
+
+ /** shear transform */
+ public void shear(double shx, double shy)
+ {
+ out.println("% shear()");
+ AffineTransform Tx = new AffineTransform();
+ Tx.shear(shx, shy);
+ transform(Tx);
+ }
+
+ /** Translates the origin of the Graphics2D context
+ to the point (x, y) in the current coordinate system. */
+ public void translate(int x, int y)
+ {
+ out.println("% translate()");
+ AffineTransform Tx = new AffineTransform();
+ Tx.translate(x, y);
+ transform(Tx);
+ }
+
+ /** Translates the origin of the Graphics2D context
+ to the point (x, y) in the current coordinate system. */
+ public void translate(double x, double y)
+ {
+ out.println("% translate(" + x + ", " + y + ")");
+ AffineTransform Tx = new AffineTransform();
+ Tx.translate(x, y);
+ transform(Tx);
+ }
+
+ /** Concatenates the current Graphics2D Transform with a rotation transform.*/
+ public void rotate(double theta)
+ {
+ out.println("% rotate(" + theta + ")");
+ AffineTransform Tx = new AffineTransform();
+ Tx.rotate(theta);
+ transform(Tx);
+ }
+
+ /** Concatenates the current Graphics2D Transform with
+ a translated rotation transform.*/
+ public void rotate(double theta, double x, double y)
+ {
+ out.println("% rotate()");
+ AffineTransform Tx = new AffineTransform();
+ Tx.rotate(theta, x, y);
+ transform(Tx);
+ }
+
+ /** Concatenates the current Graphics2D Transform with a scaling
+ transformation Subsequent rendering is resized according to the
+ specified scaling factors relative to the previous scaling.*/
+ public void scale(double sx, double sy)
+ {
+ out.println("% scale(" + sx + ", " + sy + ")");
+ AffineTransform Tx = new AffineTransform();
+ Tx.scale(sx, sy);
+ transform(Tx);
+ }
+}
diff --git a/gnu/java/awt/print/SpooledDocument.java b/gnu/java/awt/print/SpooledDocument.java
new file mode 100644
index 000000000..b606a2ef6
--- /dev/null
+++ b/gnu/java/awt/print/SpooledDocument.java
@@ -0,0 +1,91 @@
+/* SpooledDocument.java -- Reurgitate a spooled PostScript file
+ 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.java.awt.print;
+
+import javax.print.Doc;
+import javax.print.DocFlavor;
+import javax.print.attribute.DocAttributeSet;
+import java.io.File;
+import java.io.IOException;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.Reader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class SpooledDocument implements Doc
+{
+ private FileInputStream fis;
+
+ public SpooledDocument(File file)
+ {
+ try
+ {
+ fis = new FileInputStream(file);
+ }
+ catch (FileNotFoundException ffne)
+ {
+ // Shouldn't happen.
+ }
+ }
+
+ public DocAttributeSet getAttributes()
+ {
+ return null;
+ }
+
+ public DocFlavor getDocFlavor()
+ {
+ return DocFlavor.INPUT_STREAM.POSTSCRIPT;
+ }
+
+ public Object getPrintData()
+ {
+ return fis;
+ }
+
+ public Reader getReaderForText()
+ {
+ return new InputStreamReader(fis);
+ }
+
+ public InputStream getStreamForBytes()
+ {
+ return fis;
+ }
+}
diff --git a/gnu/java/lang/management/OperatingSystemMXBeanImpl.java b/gnu/java/lang/management/OperatingSystemMXBeanImpl.java
new file mode 100644
index 000000000..3ba059b36
--- /dev/null
+++ b/gnu/java/lang/management/OperatingSystemMXBeanImpl.java
@@ -0,0 +1,73 @@
+/* OperatingSystemMXBeanImpl.java - Implementation of an operating system 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 java.lang.management.OperatingSystemMXBean;
+
+/**
+ * Provides access to information about the underlying operating
+ * system.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+public final class OperatingSystemMXBeanImpl
+ implements OperatingSystemMXBean
+{
+
+ public String getArch()
+ {
+ return System.getProperty("os.arch");
+ }
+
+ public int getAvailableProcessors()
+ {
+ return Runtime.getRuntime().availableProcessors();
+ }
+
+ public String getName()
+ {
+ return System.getProperty("os.name");
+ }
+
+ public String getVersion()
+ {
+ return System.getProperty("os.version");
+ }
+
+}
diff --git a/gnu/java/lang/management/package.html b/gnu/java/lang/management/package.html
new file mode 100644
index 000000000..fc1bafc0c
--- /dev/null
+++ b/gnu/java/lang/management/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in gnu.java.lang.management package.
+ 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. -->
+
+<html>
+<head><title>GNU Classpath - gnu.java.lang.management</title></head>
+
+<body>
+<p>GNU implementations of the Java system management beans.</p>
+
+</body>
+</html>
diff --git a/gnu/java/net/IndexListParser.java b/gnu/java/net/IndexListParser.java
index 31a6dbbc8..23d2aa660 100644
--- a/gnu/java/net/IndexListParser.java
+++ b/gnu/java/net/IndexListParser.java
@@ -41,7 +41,8 @@ package gnu.java.net;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
-import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.jar.JarFile;
/**
@@ -63,10 +64,13 @@ import java.util.jar.JarFile;
*/
public class IndexListParser
{
- String filePath = "META-INF/INDEX.LIST";
- String versInfo = "JarIndex-Version: ";
+ public static final String JAR_INDEX_FILE = "META-INF/INDEX.LIST";
+ public static final String JAR_INDEX_VERSION_KEY = "JarIndex-Version: ";
+
double versionNumber;
- ArrayList headers = new ArrayList();
+ // Map each jar to the prefixes defined for the jar.
+ // This is intentionally kept in insertion order.
+ LinkedHashMap prefixes = new LinkedHashMap();
/**
* Parses the given jarfile's INDEX.LIST file if it exists.
@@ -80,35 +84,46 @@ public class IndexListParser
try
{
// Parse INDEX.LIST if it exists
- if (jarfile.getEntry(filePath) != null)
+ if (jarfile.getEntry(JAR_INDEX_FILE) != null)
{
BufferedReader br = new BufferedReader(new InputStreamReader(new URL(baseJarURL,
- filePath).openStream()));
+ JAR_INDEX_FILE).openStream()));
// Must start with version info
String line = br.readLine();
- if (!line.startsWith(versInfo))
+ if (!line.startsWith(JAR_INDEX_VERSION_KEY))
return;
- versionNumber = Double.parseDouble(line.substring(versInfo.length()).trim());
+ versionNumber = Double.parseDouble(line.substring(JAR_INDEX_VERSION_KEY.length()).trim());
// Blank line must be next
line = br.readLine();
- if (!line.equals(""))
+ if (! "".equals(line))
{
clearAll();
return;
}
- // May contain sections
- line = br.readLine();
- while (line != null)
+ // May contain sections.
+ while ((line = br.readLine()) != null)
{
- headers.add(new URL(baseURL, line));
+ URL jarURL = new URL(baseURL, line);
+ HashSet values = new HashSet();
- // Skip all names in the section
- while (! (line = br.readLine()).equals(""));
- line = br.readLine();
+ // Read the names in the section.
+ while ((line = br.readLine()) != null)
+ {
+ // Stop at section boundary.
+ if ("".equals(line))
+ break;
+ values.add(line.trim());
+ }
+ prefixes.put(jarURL, values);
+ // Might have seen an early EOF.
+ if (line == null)
+ break;
}
+
+ br.close();
}
// else INDEX.LIST does not exist
}
@@ -124,7 +139,7 @@ public class IndexListParser
void clearAll()
{
versionNumber = 0;
- headers.clear();
+ prefixes = null;
}
/**
@@ -134,7 +149,7 @@ public class IndexListParser
*/
public String getVersionInfo()
{
- return versInfo + getVersionNumber();
+ return JAR_INDEX_VERSION_KEY + getVersionNumber();
}
/**
@@ -148,12 +163,15 @@ public class IndexListParser
}
/**
- * Gets the array list of all the headers found in the file.
+ * Gets the map of all the headers found in the file.
+ * The keys in the map are URLs of jars. The values in the map
+ * are Sets of package prefixes (and top-level file names), as
+ * specifed in INDEX.LIST.
*
- * @return an array list of all the headers.
+ * @return an map of all the headers, or null if no INDEX.LIST was found
*/
- public ArrayList getHeaders()
+ public LinkedHashMap getHeaders()
{
- return headers;
+ return prefixes;
}
}
diff --git a/gnu/java/net/loader/FileResource.java b/gnu/java/net/loader/FileResource.java
new file mode 100644
index 000000000..8071bbf91
--- /dev/null
+++ b/gnu/java/net/loader/FileResource.java
@@ -0,0 +1,82 @@
+/* FileResource.java -- a Resource for file URLs
+ 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.java.net.loader;
+
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+public final class FileResource extends Resource
+{
+ final File file;
+
+ public FileResource(FileURLLoader loader, File file)
+ {
+ super(loader);
+ this.file = file;
+ }
+
+ public InputStream getInputStream() throws IOException
+ {
+ return new FileInputStream(file);
+ }
+
+ public int getLength()
+ {
+ return (int) file.length();
+ }
+
+ public URL getURL()
+ {
+ try
+ {
+ return file.toURL();
+ }
+ catch (MalformedURLException e)
+ {
+ InternalError ie = new InternalError();
+ ie.initCause(e);
+ throw ie;
+ }
+ }
+} \ No newline at end of file
diff --git a/gnu/java/net/loader/FileURLLoader.java b/gnu/java/net/loader/FileURLLoader.java
new file mode 100644
index 000000000..39d33a4e4
--- /dev/null
+++ b/gnu/java/net/loader/FileURLLoader.java
@@ -0,0 +1,145 @@
+/* FileURLLoader.java -- a URLLoader for file URLs
+ 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.java.net.loader;
+
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLStreamHandlerFactory;
+import java.util.StringTokenizer;
+
+/**
+ * A <code>FileURLLoader</code> is a type of <code>URLLoader</code>
+ * only loading from file url.
+ */
+public final class FileURLLoader extends URLLoader
+{
+ File dir; //the file for this file url
+
+ public FileURLLoader(URLClassLoader classloader,
+ URLStreamHandlerCache cache,
+ URLStreamHandlerFactory factory,
+ URL url, URL absoluteUrl)
+ {
+ super(classloader, cache, factory, url, absoluteUrl);
+ dir = new File(absoluteUrl.getFile());
+ }
+
+ /** get resource with the name "name" in the file url */
+ public Resource getResource(String name)
+ {
+ try
+ {
+ // Make sure that all components in name are valid by walking through
+ // them
+ File file = walkPathComponents(name);
+
+ if (file == null)
+ return null;
+
+ return new FileResource(this, file);
+ }
+ catch (IOException e)
+ {
+ // Fall through...
+ }
+ return null;
+ }
+
+ /**
+ * Walk all path tokens and check them for validity. At no moment, we are
+ * allowed to reach a directory located "above" the root directory, stored
+ * in "dir" property. We are also not allowed to enter a non existing
+ * directory or a non directory component (plain file, symbolic link, ...).
+ * An empty or null path is valid. Pathnames components are separated by
+ * <code>File.separatorChar</code>
+ *
+ * @param resourceFileName the name to be checked for validity.
+ * @return the canonical file pointed by the resourceFileName or null if the
+ * walking failed
+ * @throws IOException in case of issue when creating the canonical
+ * resulting file
+ * @see File#separatorChar
+ */
+ private File walkPathComponents(String resourceFileName) throws IOException
+ {
+ StringTokenizer stringTokenizer = new StringTokenizer(resourceFileName, File.separator);
+ File currentFile = dir;
+ int tokenCount = stringTokenizer.countTokens();
+
+ for (int i = 0; i < tokenCount - 1; i++)
+ {
+ String currentToken = stringTokenizer.nextToken();
+
+ // If we are at the root directory and trying to go up, the walking is
+ // finished with an error
+ if ("..".equals(currentToken) && currentFile.equals(dir))
+ return null;
+
+ currentFile = new File(currentFile, currentToken);
+
+ // If the current file doesn't exist or is not a directory, the walking is
+ // finished with an error
+ if (! (currentFile.exists() && currentFile.isDirectory()))
+ return null;
+
+ }
+
+ // Treat the last token differently, if it exists, because it does not need
+ // to be a directory
+ if (tokenCount > 0)
+ {
+ String currentToken = stringTokenizer.nextToken();
+
+ if ("..".equals(currentToken) && currentFile.equals(dir))
+ return null;
+
+ currentFile = new File(currentFile, currentToken);
+
+ // If the current file doesn't exist, the walking is
+ // finished with an error
+ if (! currentFile.exists())
+ return null;
+ }
+
+ return currentFile.getCanonicalFile();
+ }
+} \ No newline at end of file
diff --git a/gnu/java/net/loader/JarURLLoader.java b/gnu/java/net/loader/JarURLLoader.java
new file mode 100644
index 000000000..1e6b6bdaa
--- /dev/null
+++ b/gnu/java/net/loader/JarURLLoader.java
@@ -0,0 +1,210 @@
+package gnu.java.net.loader;
+
+import gnu.java.net.IndexListParser;
+
+import java.io.IOException;
+import java.net.JarURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLStreamHandlerFactory;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+/**
+ * A <code>JarURLLoader</code> is a type of <code>URLLoader</code>
+ * only loading from jar url.
+ */
+public final class JarURLLoader extends URLLoader
+{
+ // True if we've initialized -- i.e., tried open the jar file.
+ boolean initialized;
+ // The jar file for this url.
+ JarFile jarfile;
+ // Base jar: url for all resources loaded from jar.
+ final URL baseJarURL;
+ // The "Class-Path" attribute of this Jar's manifest.
+ ArrayList classPath;
+ // If not null, a mapping from INDEX.LIST for this jar only.
+ // This is a set of all prefixes and top-level files that
+ // ought to be available in this jar.
+ Set indexSet;
+
+ // This constructor is used internally. It purposely does not open
+ // the jar file -- it defers this until later. This allows us to
+ // implement INDEX.LIST lazy-loading semantics.
+ private JarURLLoader(URLClassLoader classloader, URLStreamHandlerCache cache,
+ URLStreamHandlerFactory factory,
+ URL baseURL, URL absoluteUrl,
+ Set indexSet)
+ {
+ super(classloader, cache, factory, baseURL, absoluteUrl);
+
+ URL newBaseURL = null;
+ try
+ {
+ // Cache url prefix for all resources in this jar url.
+ String base = baseURL.toExternalForm() + "!/";
+ newBaseURL = new URL("jar", "", -1, base, cache.get(factory, "jar"));
+ }
+ catch (MalformedURLException ignore)
+ {
+ // Ignore.
+ }
+ this.baseJarURL = newBaseURL;
+ this.classPath = null;
+ this.indexSet = indexSet;
+ }
+
+ // This constructor is used by URLClassLoader. It will immediately
+ // try to read the jar file, in case we've found an index or a class-path
+ // setting. FIXME: it would be nice to defer this as well, but URLClassLoader
+ // makes this hard.
+ public JarURLLoader(URLClassLoader classloader, URLStreamHandlerCache cache,
+ URLStreamHandlerFactory factory,
+ URL baseURL, URL absoluteUrl)
+ {
+ this(classloader, cache, factory, baseURL, absoluteUrl, null);
+ initialize();
+ }
+
+ private void initialize()
+ {
+ JarFile jarfile = null;
+ try
+ {
+ jarfile =
+ ((JarURLConnection) baseJarURL.openConnection()).getJarFile();
+
+ Manifest manifest;
+ Attributes attributes;
+ String classPathString;
+
+ IndexListParser parser = new IndexListParser(jarfile, baseJarURL,
+ baseURL);
+ LinkedHashMap indexMap = parser.getHeaders();
+ if (indexMap != null)
+ {
+ // Note that the index also computes
+ // the resulting Class-Path -- there are jars out there
+ // where the index lists some required jars which do
+ // not appear in the Class-Path attribute in the manifest.
+ this.classPath = new ArrayList();
+ Iterator it = indexMap.entrySet().iterator();
+ while (it.hasNext())
+ {
+ Map.Entry entry = (Map.Entry) it.next();
+ URL subURL = (URL) entry.getKey();
+ Set prefixes = (Set) entry.getValue();
+ if (subURL.equals(baseURL))
+ this.indexSet = prefixes;
+ else
+ {
+ JarURLLoader subLoader = new JarURLLoader(classloader,
+ cache,
+ factory, subURL,
+ subURL,
+ prefixes);
+ // Note that we don't care if the sub-loader itself has an
+ // index or a class-path -- only the top-level jar
+ // file gets this treatment; its index should cover
+ // everything.
+ this.classPath.add(subLoader);
+ }
+ }
+ }
+ else if ((manifest = jarfile.getManifest()) != null
+ && (attributes = manifest.getMainAttributes()) != null
+ && ((classPathString
+ = attributes.getValue(Attributes.Name.CLASS_PATH))
+ != null))
+ {
+ this.classPath = new ArrayList();
+ StringTokenizer st = new StringTokenizer(classPathString, " ");
+ while (st.hasMoreElements ())
+ {
+ String e = st.nextToken ();
+ try
+ {
+ URL subURL = new URL(baseURL, e);
+ JarURLLoader subLoader = new JarURLLoader(classloader,
+ cache, factory,
+ subURL, subURL);
+ this.classPath.add(subLoader);
+ ArrayList extra = subLoader.getClassPath();
+ if (extra != null)
+ this.classPath.addAll(extra);
+ }
+ catch (java.net.MalformedURLException xx)
+ {
+ // Give up
+ }
+ }
+ }
+ }
+ catch (IOException ioe)
+ {
+ /* ignored */
+ }
+
+ this.jarfile = jarfile;
+ this.initialized = true;
+ }
+
+ /** get resource with the name "name" in the jar url */
+ public Resource getResource(String name)
+ {
+ if (name.startsWith("/"))
+ name = name.substring(1);
+ if (indexSet != null)
+ {
+ // Trust the index.
+ String basename = name;
+ int offset = basename.lastIndexOf('/');
+ if (offset != -1)
+ basename = basename.substring(0, offset);
+ if (! indexSet.contains(basename))
+ return null;
+ // FIXME: if the index claim to hold the resource, and jar file
+ // doesn't have it, we're supposed to throw an exception. However,
+ // in our model this is tricky to implement, as another URLLoader from
+ // the same top-level jar may have an overlapping index entry.
+ }
+
+ if (! initialized)
+ initialize();
+ if (jarfile == null)
+ return null;
+
+ JarEntry je = jarfile.getJarEntry(name);
+ if (je != null)
+ return new JarURLResource(this, name, je);
+ else
+ return null;
+ }
+
+ public Manifest getManifest()
+ {
+ try
+ {
+ return (jarfile == null) ? null : jarfile.getManifest();
+ }
+ catch (IOException ioe)
+ {
+ return null;
+ }
+ }
+
+ public ArrayList getClassPath()
+ {
+ return classPath;
+ }
+}
diff --git a/gnu/java/net/loader/JarURLResource.java b/gnu/java/net/loader/JarURLResource.java
new file mode 100644
index 000000000..a9db5ce0b
--- /dev/null
+++ b/gnu/java/net/loader/JarURLResource.java
@@ -0,0 +1,94 @@
+/* JarURLResource.java -- a Resource for jar URLs
+ 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.java.net.loader;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.cert.Certificate;
+import java.util.jar.JarEntry;
+
+public final class JarURLResource extends Resource
+{
+ private final JarEntry entry;
+ private final String name;
+
+ public JarURLResource(JarURLLoader loader, String name, JarEntry entry)
+ {
+ super(loader);
+ this.entry = entry;
+ this.name = name;
+ }
+
+ public InputStream getInputStream() throws IOException
+ {
+ return ((JarURLLoader) loader).jarfile.getInputStream(entry);
+ }
+
+ public int getLength()
+ {
+ return (int) entry.getSize();
+ }
+
+ public Certificate[] getCertificates()
+ {
+ // We have to get the entry from the jar file again, because the
+ // certificates will not be available until the entire entry has
+ // been read.
+ return ((JarEntry) ((JarURLLoader) loader).jarfile.getEntry(name))
+ .getCertificates();
+ }
+
+ public URL getURL()
+ {
+ try
+ {
+ return new URL(((JarURLLoader) loader).baseJarURL, name,
+ loader.cache.get(loader.factory, "jar"));
+ }
+ catch (MalformedURLException e)
+ {
+ InternalError ie = new InternalError();
+ ie.initCause(e);
+ throw ie;
+ }
+ }
+} \ No newline at end of file
diff --git a/gnu/java/net/loader/RemoteResource.java b/gnu/java/net/loader/RemoteResource.java
new file mode 100644
index 000000000..f18031581
--- /dev/null
+++ b/gnu/java/net/loader/RemoteResource.java
@@ -0,0 +1,78 @@
+/* Resource.java -- a Resource for "remote" URLs
+ 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.java.net.loader;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+/**
+ * A resource from some remote location.
+ */
+public final class RemoteResource extends Resource
+{
+ private final URL url;
+ private final InputStream stream;
+ final int length;
+
+ public RemoteResource(RemoteURLLoader loader, String name, URL url,
+ InputStream stream, int length)
+ {
+ super(loader);
+ this.url = url;
+ this.stream = stream;
+ this.length = length;
+ }
+
+ public InputStream getInputStream() throws IOException
+ {
+ return stream;
+ }
+
+ public int getLength()
+ {
+ return length;
+ }
+
+ public URL getURL()
+ {
+ return url;
+ }
+} \ No newline at end of file
diff --git a/gnu/java/net/loader/RemoteURLLoader.java b/gnu/java/net/loader/RemoteURLLoader.java
new file mode 100644
index 000000000..f044740fa
--- /dev/null
+++ b/gnu/java/net/loader/RemoteURLLoader.java
@@ -0,0 +1,101 @@
+/* RemoteURLLoader.java -- a URLLoader for "remote" objects
+ 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.java.net.loader;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLConnection;
+import java.net.URLStreamHandlerFactory;
+
+/**
+ * Loader for remote directories.
+ */
+public final class RemoteURLLoader extends URLLoader
+{
+ private final String protocol;
+
+ public RemoteURLLoader(URLClassLoader classloader,
+ URLStreamHandlerCache cache,
+ URLStreamHandlerFactory factory,
+ URL url)
+ {
+ super(classloader, cache, factory, url);
+ protocol = url.getProtocol();
+ }
+
+ /**
+ * Get a remote resource.
+ * Returns null if no such resource exists.
+ */
+ public Resource getResource(String name)
+ {
+ try
+ {
+ URL url = new URL(baseURL, name, cache.get(factory, protocol));
+ URLConnection connection = url.openConnection();
+
+ // Open the connection and check the stream
+ // just to be sure it exists.
+ int length = connection.getContentLength();
+ InputStream stream = connection.getInputStream();
+
+ // We can do some extra checking if it is a http request
+ if (connection instanceof HttpURLConnection)
+ {
+ int response =
+ ((HttpURLConnection) connection).getResponseCode();
+ if (response / 100 != 2)
+ return null;
+ }
+
+ if (stream != null)
+ return new RemoteResource(this, name, url, stream, length);
+ else
+ return null;
+ }
+ catch (IOException ioe)
+ {
+ return null;
+ }
+ }
+} \ No newline at end of file
diff --git a/gnu/java/net/loader/Resource.java b/gnu/java/net/loader/Resource.java
new file mode 100644
index 000000000..e367a3388
--- /dev/null
+++ b/gnu/java/net/loader/Resource.java
@@ -0,0 +1,110 @@
+/* Resource.java -- a resource for URLLoader
+ 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.java.net.loader;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.security.CodeSource;
+import java.security.cert.Certificate;
+
+/**
+ * A <code>Resource</code> represents a resource in some
+ * <code>URLLoader</code>. It also contains all information (e.g.,
+ * <code>URL</code>, <code>CodeSource</code>, <code>Manifest</code> and
+ * <code>InputStream</code>) that is necessary for loading resources
+ * and creating classes from a <code>URL</code>.
+ */
+public abstract class Resource
+{
+ final URLLoader loader;
+
+ public Resource(URLLoader loader)
+ {
+ this.loader = loader;
+ }
+
+ /**
+ * Returns the non-null <code>CodeSource</code> associated with
+ * this resource.
+ */
+ public CodeSource getCodeSource()
+ {
+ Certificate[] certs = getCertificates();
+ if (certs == null)
+ return loader.noCertCodeSource;
+ else
+ return new CodeSource(loader.baseURL, certs);
+ }
+
+ /**
+ * Returns <code>Certificates</code> associated with this
+ * resource, or null when there are none.
+ */
+ public Certificate[] getCertificates()
+ {
+ return null;
+ }
+
+ /**
+ * Return the URLLoader for this resource.
+ */
+ public final URLLoader getLoader()
+ {
+ return loader;
+ }
+
+ /**
+ * Return a <code>URL</code> that can be used to access this resource.
+ */
+ public abstract URL getURL();
+
+ /**
+ * Returns the size of this <code>Resource</code> in bytes or
+ * <code>-1</code> when unknown.
+ */
+ public abstract int getLength();
+
+ /**
+ * Returns the non-null <code>InputStream</code> through which
+ * this resource can be loaded.
+ */
+ public abstract InputStream getInputStream() throws IOException;
+} \ No newline at end of file
diff --git a/gnu/java/net/loader/URLLoader.java b/gnu/java/net/loader/URLLoader.java
new file mode 100644
index 000000000..d073c5429
--- /dev/null
+++ b/gnu/java/net/loader/URLLoader.java
@@ -0,0 +1,147 @@
+/* URLLoader.java -- base helper class for URLClassLoader
+ 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.java.net.loader;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLStreamHandlerFactory;
+import java.security.CodeSource;
+import java.util.ArrayList;
+import java.util.jar.Manifest;
+
+/**
+ * A <code>URLLoader</code> contains all logic to load resources from a
+ * given base <code>URL</code>.
+ */
+public abstract class URLLoader
+{
+ /**
+ * Our classloader to get info from if needed.
+ */
+ final URLClassLoader classloader;
+
+ /**
+ * The base URL from which all resources are loaded.
+ */
+ final URL baseURL;
+
+ /**
+ * The stream handler factory.
+ */
+ final URLStreamHandlerFactory factory;
+
+ /**
+ * The source for stream handlers.
+ */
+ final URLStreamHandlerCache cache;
+
+ /**
+ * A <code>CodeSource</code> without any associated certificates.
+ * It is common for classes to not have certificates associated
+ * with them. If they come from the same <code>URLLoader</code>
+ * then it is safe to share the associated <code>CodeSource</code>
+ * between them since <code>CodeSource</code> is immutable.
+ */
+ final CodeSource noCertCodeSource;
+
+ public URLLoader(URLClassLoader classloader, URLStreamHandlerCache cache,
+ URLStreamHandlerFactory factory,
+ URL baseURL)
+ {
+ this(classloader, cache, factory, baseURL, baseURL);
+ }
+
+ public URLLoader(URLClassLoader classloader, URLStreamHandlerCache cache,
+ URLStreamHandlerFactory factory,
+ URL baseURL, URL overrideURL)
+ {
+ this.classloader = classloader;
+ this.baseURL = baseURL;
+ this.factory = factory;
+ this.cache = cache;
+ this.noCertCodeSource = new CodeSource(overrideURL, null);
+ }
+
+ /**
+ * Return the base URL of this loader.
+ */
+ public final URL getBaseURL()
+ {
+ return baseURL;
+ }
+
+ /**
+ * Returns a <code>Class</code> loaded by this
+ * <code>URLLoader</code>, or <code>null</code> when this loader
+ * either can't load the class or doesn't know how to load classes
+ * at all. Most subclasses do not need to override this; it is only
+ * useful in situations where the subclass has a more direct way of
+ * making <code>Class</code> objects.
+ */
+ public Class getClass(String className)
+ {
+ return null;
+ }
+
+ /**
+ * Returns a <code>Resource</code> loaded by this
+ * <code>URLLoader</code>, or <code>null</code> when no
+ * <code>Resource</code> with the given name exists.
+ */
+ public abstract Resource getResource(String s);
+
+ /**
+ * Returns the <code>Manifest</code> associated with the
+ * <code>Resource</code>s loaded by this <code>URLLoader</code> or
+ * <code>null</code> there is no such <code>Manifest</code>.
+ */
+ public Manifest getManifest()
+ {
+ return null;
+ }
+
+ /**
+ * Return a list of new URLLoader objects representing any
+ * class path entries added by this container.
+ */
+ public ArrayList getClassPath()
+ {
+ return null;
+ }
+} \ No newline at end of file
diff --git a/gnu/java/net/loader/URLStreamHandlerCache.java b/gnu/java/net/loader/URLStreamHandlerCache.java
new file mode 100644
index 000000000..295a15d2b
--- /dev/null
+++ b/gnu/java/net/loader/URLStreamHandlerCache.java
@@ -0,0 +1,84 @@
+/* URLStreamHandlerCache.java -- a cache for URLStreamHandlers
+ 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.java.net.loader;
+
+import java.net.URLStreamHandler;
+import java.net.URLStreamHandlerFactory;
+import java.util.HashMap;
+
+/**
+ */
+public class URLStreamHandlerCache
+{
+ /**
+ * A cache to store mappings between handler factory and its
+ * private protocol handler cache (also a HashMap), so we can avoid
+ * creating handlers each time the same protocol comes.
+ */
+ private HashMap factoryCache = new HashMap(5);
+
+ public URLStreamHandlerCache()
+ {
+ }
+
+ public synchronized void add(URLStreamHandlerFactory factory)
+ {
+ // Since we only support three protocols so far, 5 is enough
+ // for cache initial size.
+ if (factory != null && factoryCache.get(factory) == null)
+ factoryCache.put(factory, new HashMap(5));
+ }
+
+ public synchronized URLStreamHandler get(URLStreamHandlerFactory factory,
+ String protocol)
+ {
+ if (factory == null)
+ return null;
+ // Check if there're handler for the same protocol in cache.
+ HashMap cache = (HashMap) factoryCache.get(factory);
+ URLStreamHandler handler = (URLStreamHandler) cache.get(protocol);
+ if (handler == null)
+ {
+ // Add it to cache.
+ handler = factory.createURLStreamHandler(protocol);
+ cache.put(protocol, handler);
+ }
+ return handler;
+ }
+}
diff --git a/gnu/java/net/protocol/http/HTTPConnection.java b/gnu/java/net/protocol/http/HTTPConnection.java
index 33d9756aa..f5e831c6a 100644
--- a/gnu/java/net/protocol/http/HTTPConnection.java
+++ b/gnu/java/net/protocol/http/HTTPConnection.java
@@ -466,7 +466,8 @@ public class HTTPConnection
*/
synchronized HTTPConnection get(String host,
int port,
- boolean secure)
+ boolean secure,
+ int connectionTimeout, int timeout)
{
String ttl =
SystemProperties.getProperty("classpath.net.http.keepAliveTTL");
@@ -494,7 +495,7 @@ public class HTTPConnection
}
if (c == null)
{
- c = new HTTPConnection(host, port, secure);
+ c = new HTTPConnection(host, port, secure, connectionTimeout, timeout);
c.setPool(this);
}
return c;
diff --git a/gnu/java/net/protocol/http/HTTPURLConnection.java b/gnu/java/net/protocol/http/HTTPURLConnection.java
index 0dce7c75b..a46d1204b 100644
--- a/gnu/java/net/protocol/http/HTTPURLConnection.java
+++ b/gnu/java/net/protocol/http/HTTPURLConnection.java
@@ -65,7 +65,7 @@ import javax.net.ssl.SSLSocketFactory;
* @author Chris Burdess (dog@gnu.org)
*/
public class HTTPURLConnection
- extends HttpsURLConnection
+ extends HttpsURLConnection
implements HandshakeCompletedListener
{
/*
@@ -346,11 +346,11 @@ public class HTTPURLConnection
HTTPConnection connection;
if (keepAlive)
{
- connection = HTTPConnection.Pool.instance.get(host, port, secure);
+ connection = HTTPConnection.Pool.instance.get(host, port, secure, getConnectTimeout(), 0);
}
else
{
- connection = new HTTPConnection(host, port, secure);
+ connection = new HTTPConnection(host, port, secure, 0, getConnectTimeout());
}
return connection;
}
@@ -653,5 +653,27 @@ public class HTTPURLConnection
handshakeEvent = event;
}
+ /**
+ * Set the connection timeout speed, in milliseconds, or zero if the timeout
+ * is to be considered infinite.
+ *
+ * Overloaded.
+ *
+ */
+ public void setConnectTimeout(int timeout)
+ throws IllegalArgumentException
+ {
+ super.setConnectTimeout( timeout );
+ if( connection == null )
+ return;
+ try
+ {
+ connection.getSocket().setSoTimeout( timeout );
+ }
+ catch(IOException se)
+ {
+ // Ignore socket exceptions.
+ }
+ }
}
diff --git a/gnu/java/net/protocol/jar/Connection.java b/gnu/java/net/protocol/jar/Connection.java
index 41c5d6dcf..f99806ae4 100644
--- a/gnu/java/net/protocol/jar/Connection.java
+++ b/gnu/java/net/protocol/jar/Connection.java
@@ -188,7 +188,7 @@ public final class Connection extends JarURLConnection
else if (field.equals("last-modified"))
{
// Both creating and manipulating dateFormat need synchronization.
- synchronized (this.getClass())
+ synchronized (Connection.class)
{
if (dateFormat == null)
dateFormat = new SimpleDateFormat
diff --git a/gnu/java/nio/PipeImpl.java b/gnu/java/nio/PipeImpl.java
index f7b01c8b7..cccaa3988 100644
--- a/gnu/java/nio/PipeImpl.java
+++ b/gnu/java/nio/PipeImpl.java
@@ -37,6 +37,7 @@ exception statement from your version. */
package gnu.java.nio;
+
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.Pipe;
@@ -47,12 +48,14 @@ class PipeImpl extends Pipe
public static final class SourceChannelImpl extends Pipe.SourceChannel
{
private int native_fd;
+ private VMChannel vmch;
public SourceChannelImpl (SelectorProvider selectorProvider,
int native_fd)
{
super (selectorProvider);
this.native_fd = native_fd;
+ vmch = VMChannel.getVMChannel(this);
}
protected final void implCloseSelectableChannel()
@@ -64,19 +67,19 @@ class PipeImpl extends Pipe
protected void implConfigureBlocking (boolean blocking)
throws IOException
{
- throw new Error ("Not implemented");
+ vmch.setBlocking(blocking);
}
public final int read (ByteBuffer src)
throws IOException
{
- throw new Error ("Not implemented");
+ return vmch.read(src);
}
public final long read (ByteBuffer[] srcs)
throws IOException
{
- return read (srcs, 0, srcs.length);
+ return vmch.readScattering(srcs, 0, srcs.length);
}
public final synchronized long read (ByteBuffer[] srcs, int offset,
@@ -89,13 +92,7 @@ class PipeImpl extends Pipe
|| len > srcs.length - offset)
throw new IndexOutOfBoundsException();
- long bytesRead = 0;
-
- for (int index = 0; index < len; index++)
- bytesRead += read (srcs [offset + index]);
-
- return bytesRead;
-
+ return vmch.readScattering(srcs, offset, len);
}
public final int getNativeFD()
@@ -107,12 +104,14 @@ class PipeImpl extends Pipe
public static final class SinkChannelImpl extends Pipe.SinkChannel
{
private int native_fd;
+ private VMChannel vmch;
public SinkChannelImpl (SelectorProvider selectorProvider,
int native_fd)
{
super (selectorProvider);
this.native_fd = native_fd;
+ vmch = VMChannel.getVMChannel(this);
}
protected final void implCloseSelectableChannel()
@@ -124,19 +123,19 @@ class PipeImpl extends Pipe
protected final void implConfigureBlocking (boolean blocking)
throws IOException
{
- throw new Error ("Not implemented");
+ vmch.setBlocking(blocking);
}
public final int write (ByteBuffer dst)
throws IOException
{
- throw new Error ("Not implemented");
+ return vmch.write(dst);
}
public final long write (ByteBuffer[] srcs)
throws IOException
{
- return write (srcs, 0, srcs.length);
+ return vmch.writeGathering(srcs, 0, srcs.length);
}
public final synchronized long write (ByteBuffer[] srcs, int offset, int len)
@@ -147,13 +146,8 @@ class PipeImpl extends Pipe
|| len < 0
|| len > srcs.length - offset)
throw new IndexOutOfBoundsException();
-
- long bytesWritten = 0;
- for (int index = 0; index < len; index++)
- bytesWritten += write (srcs [offset + index]);
-
- return bytesWritten;
+ return vmch.writeGathering(srcs, offset, len);
}
public final int getNativeFD()
diff --git a/gnu/java/nio/SelectorImpl.java b/gnu/java/nio/SelectorImpl.java
index e10f71574..7639c9ae3 100644
--- a/gnu/java/nio/SelectorImpl.java
+++ b/gnu/java/nio/SelectorImpl.java
@@ -379,6 +379,8 @@ public class SelectorImpl extends AbstractSelector
result = new DatagramChannelSelectionKey (ch, this);
else if (ch instanceof ServerSocketChannelImpl)
result = new ServerSocketChannelSelectionKey (ch, this);
+ else if (ch instanceof gnu.java.nio.SocketChannelImpl)
+ result = new gnu.java.nio.SocketChannelSelectionKeyImpl((gnu.java.nio.SocketChannelImpl)ch, this);
else
throw new InternalError ("No known channel type");
diff --git a/gnu/java/nio/SocketChannelSelectionKeyImpl.java b/gnu/java/nio/SocketChannelSelectionKeyImpl.java
new file mode 100644
index 000000000..30fb2dfba
--- /dev/null
+++ b/gnu/java/nio/SocketChannelSelectionKeyImpl.java
@@ -0,0 +1,69 @@
+/* SocketChannelSelectionKey.java -- Selection key for Socket Channel
+ 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 gnu.java.nio;
+
+
+/**
+ * @author Michael Barker <mike@middlesoft.co.uk>
+ *
+ */
+public class SocketChannelSelectionKeyImpl extends SelectionKeyImpl
+{
+
+ SocketChannelImpl ch;
+
+ /**
+ * @param ch
+ * @param impl
+ */
+ public SocketChannelSelectionKeyImpl(SocketChannelImpl ch, SelectorImpl impl)
+ {
+ super(ch, impl);
+ this.ch = (SocketChannelImpl) ch;
+ }
+
+ /**
+ * Returns the native file/socket descriptor as an int.
+ */
+ public int getNativeFD()
+ {
+ return ch.getPlainSocketImpl().getNativeFD();
+ }
+
+}
diff --git a/gnu/java/nio/channels/FileChannelImpl.java b/gnu/java/nio/channels/FileChannelImpl.java
index 671ae5bb1..ed439e141 100644
--- a/gnu/java/nio/channels/FileChannelImpl.java
+++ b/gnu/java/nio/channels/FileChannelImpl.java
@@ -40,6 +40,7 @@ package gnu.java.nio.channels;
import gnu.classpath.Configuration;
import gnu.java.nio.FileLockImpl;
+import gnu.java.nio.VMChannel;
import java.io.File;
import java.io.FileNotFoundException;
@@ -102,6 +103,7 @@ public final class FileChannelImpl extends FileChannel
// we want to make sure this has the value -1. This is the most
// efficient way to accomplish that.
private int fd = -1;
+ private VMChannel ch;
private int mode;
@@ -123,6 +125,7 @@ public final class FileChannelImpl extends FileChannel
description = path;
fd = open (path, mode);
this.mode = mode;
+ this.ch = VMChannel.getVMChannel(this);
// First open the file and then check if it is a a directory
// to avoid race condition.
@@ -155,6 +158,7 @@ public final class FileChannelImpl extends FileChannel
this.fd = fd;
this.mode = mode;
this.description = "descriptor(" + fd + ")";
+ this.ch = VMChannel.getVMChannel(this);
}
private native int open (String path, int mode) throws FileNotFoundException;
@@ -181,6 +185,7 @@ public final class FileChannelImpl extends FileChannel
public int read (ByteBuffer dst) throws IOException
{
+ /*
int result;
byte[] buffer = new byte [dst.remaining ()];
@@ -190,6 +195,8 @@ public final class FileChannelImpl extends FileChannel
dst.put (buffer, 0, result);
return result;
+ */
+ return ch.read(dst);
}
public int read (ByteBuffer dst, long position)
@@ -214,33 +221,12 @@ public final class FileChannelImpl extends FileChannel
public long read (ByteBuffer[] dsts, int offset, int length)
throws IOException
{
- long result = 0;
-
- for (int i = offset; i < offset + length; i++)
- {
- result += read (dsts [i]);
- }
-
- return result;
+ return ch.readScattering(dsts, offset, length);
}
public int write (ByteBuffer src) throws IOException
{
- int len = src.remaining ();
- if (src.hasArray())
- {
- byte[] buffer = src.array();
- write(buffer, src.arrayOffset() + src.position(), len);
- src.position(src.position() + len);
- }
- else
- {
- // Use a more efficient native method! FIXME!
- byte[] buffer = new byte [len];
- src.get (buffer, 0, len);
- write (buffer, 0, len);
- }
- return len;
+ return ch.write(src);
}
public int write (ByteBuffer src, long position)
@@ -274,14 +260,7 @@ public final class FileChannelImpl extends FileChannel
public long write(ByteBuffer[] srcs, int offset, int length)
throws IOException
{
- long result = 0;
-
- for (int i = offset;i < offset + length;i++)
- {
- result += write (srcs[i]);
- }
-
- return result;
+ return ch.writeGathering(srcs, offset, length);
}
public native MappedByteBuffer mapImpl (char mode, long position, int size)
@@ -563,4 +542,12 @@ public final class FileChannelImpl extends FileChannel
+ ",mode=" + mode + ","
+ description + "]");
}
+
+ /**
+ * @return The native file descriptor.
+ */
+ public int getNativeFD()
+ {
+ return fd;
+ }
}
diff --git a/gnu/java/security/OID.java b/gnu/java/security/OID.java
index 473b6ba5a..822ca3427 100644
--- a/gnu/java/security/OID.java
+++ b/gnu/java/security/OID.java
@@ -1,5 +1,5 @@
/* OID.java -- numeric representation of an object identifier
- Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -211,7 +211,6 @@ public class OID implements Cloneable, Comparable, java.io.Serializable
/**
* Construct a new OID from the given DER bytes.
*
- * @param root The root OID.
* @param encoded The encoded relative OID.
* @param relative The relative flag.
*/
diff --git a/gnu/java/security/PolicyFile.java b/gnu/java/security/PolicyFile.java
index 3064f041b..8404eeb98 100644
--- a/gnu/java/security/PolicyFile.java
+++ b/gnu/java/security/PolicyFile.java
@@ -1,5 +1,5 @@
/* PolicyFile.java -- policy file reader
- Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -148,7 +148,7 @@ public final class PolicyFile extends Policy
// Constants and fields.
// -------------------------------------------------------------------------
- private static final Logger logger = SystemLogger.SYSTEM;
+ protected static final Logger logger = SystemLogger.SYSTEM;
private static final String DEFAULT_POLICY =
SystemProperties.getProperty("java.home")
diff --git a/gnu/java/security/hash/MD4.java b/gnu/java/security/hash/MD4.java
index a09eb1705..215cd9837 100644
--- a/gnu/java/security/hash/MD4.java
+++ b/gnu/java/security/hash/MD4.java
@@ -44,7 +44,7 @@ import gnu.java.security.util.Util;
/**
* <p>An implementation of Ron Rivest's MD4 message digest algorithm.</p>
*
- * <p>MD4 was the precursor to the stronger {@link gnu.crypto.hash.MD5}
+ * <p>MD4 was the precursor to the stronger {@link gnu.java.security.hash.MD5}
* algorithm, and while not considered cryptograpically secure itself, MD4 is
* in use in various applications. It is slightly faster than MD5.</p>
*
diff --git a/gnu/java/security/prng/PRNGFactory.java b/gnu/java/security/prng/PRNGFactory.java
index 8b5141456..1699d9e7e 100644
--- a/gnu/java/security/prng/PRNGFactory.java
+++ b/gnu/java/security/prng/PRNGFactory.java
@@ -42,7 +42,6 @@ import gnu.java.security.Registry;
import java.util.Collections;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.Set;
/**
diff --git a/gnu/java/security/provider/PKIXCertPathValidatorImpl.java b/gnu/java/security/provider/PKIXCertPathValidatorImpl.java
index 880163731..448a609ec 100644
--- a/gnu/java/security/provider/PKIXCertPathValidatorImpl.java
+++ b/gnu/java/security/provider/PKIXCertPathValidatorImpl.java
@@ -1,5 +1,5 @@
/* PKIXCertPathValidatorImpl.java -- PKIX certificate path validator.
- Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -435,7 +435,7 @@ public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi
* @param crl The CRL being checked.
* @param path The path this CRL is being checked against.
* @param now The value to use as 'now'.
- * @param pubKeySubject The subject of the public key.
+ * @param pubKeyCert The certificate authenticating the public key.
* @param pubKey The public key to check.
* @return True if the CRL is acceptable.
*/
diff --git a/gnu/java/security/sig/ISignature.java b/gnu/java/security/sig/ISignature.java
index e77f39d2c..9ad853a29 100644
--- a/gnu/java/security/sig/ISignature.java
+++ b/gnu/java/security/sig/ISignature.java
@@ -71,9 +71,9 @@ public interface ISignature extends Cloneable
/**
* Property name of an optional {@link java.security.SecureRandom},
- * {@link java.util.Random}, or {@link gnu.crypto.prng.IRandom} instance to
+ * {@link java.util.Random}, or {@link gnu.java.security.prng.IRandom} instance to
* use. The default is to use a classloader singleton from
- * {@link gnu.crypto.util.PRNG}.
+ * {@link gnu.java.security.util.PRNG}.
*/
public static final String SOURCE_OF_RANDOMNESS = "gnu.crypto.sig.prng";
diff --git a/gnu/java/security/sig/rsa/RSAPSSSignatureRawCodec.java b/gnu/java/security/sig/rsa/RSAPSSSignatureRawCodec.java
index 2be79165f..1ae295e36 100644
--- a/gnu/java/security/sig/rsa/RSAPSSSignatureRawCodec.java
+++ b/gnu/java/security/sig/rsa/RSAPSSSignatureRawCodec.java
@@ -44,7 +44,7 @@ import gnu.java.security.sig.ISignatureCodec;
import java.io.ByteArrayOutputStream;
/**
- * <p>An object that implements the {@link gnu.crypto.sig.ISignatureCodec}
+ * <p>An object that implements the {@link ISignatureCodec}
* operations for the <i>Raw</i> format to use with RSA-PSS signatures.</p>
*/
public class RSAPSSSignatureRawCodec implements ISignatureCodec
diff --git a/gnu/java/security/util/ExpirableObject.java b/gnu/java/security/util/ExpirableObject.java
index 2d4452015..c14b75957 100644
--- a/gnu/java/security/util/ExpirableObject.java
+++ b/gnu/java/security/util/ExpirableObject.java
@@ -51,7 +51,7 @@ import javax.security.auth.Destroyable;
* once a timeout elapses, will automatically call the {@link
* Destroyable#destroy()} method.
*
- * <p>Concrete subclasses must implement the {@link doDestroy()} method
+ * <p>Concrete subclasses must implement the {@link #doDestroy()} method
* instead of {@link Destroyable#destroy()}; the behavior of that method
* should match exactly the behavior desired of <code>destroy()</code>.
*
@@ -111,7 +111,7 @@ public abstract class ExpirableObject implements Destroyable
// -------------------------------------------------------------------------
/**
- * Destroys this object. This method calls {@link doDestroy}, then, if
+ * Destroys this object. This method calls {@link #doDestroy}, then, if
* no exception is thrown, cancels the task that would destroy this object
* when the timeout is reached.
*
diff --git a/gnu/java/security/util/SimpleList.java b/gnu/java/security/util/SimpleList.java
index b2525c4b8..8636b4e14 100644
--- a/gnu/java/security/util/SimpleList.java
+++ b/gnu/java/security/util/SimpleList.java
@@ -61,7 +61,7 @@ public final class SimpleList extends AbstractList
/**
* Create a singleton list.
*
- * @param e1 The first element.
+ * @param element The first element.
*/
public SimpleList(final Object element)
{
diff --git a/gnu/java/security/x509/Util.java b/gnu/java/security/x509/Util.java
index d27392026..1bd268a51 100644
--- a/gnu/java/security/x509/Util.java
+++ b/gnu/java/security/x509/Util.java
@@ -1,5 +1,5 @@
/* Util.java -- Miscellaneous utility methods.
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -155,7 +155,7 @@ public final class Util
}
/**
- * See {@link #hexDump(byte[],int,int)}.
+ * See {@link #hexDump(byte[],int,int,String)}.
*/
public static String hexDump(byte[] buf, String prefix)
{
diff --git a/gnu/java/security/x509/ext/GeneralNames.java b/gnu/java/security/x509/ext/GeneralNames.java
index dae94cd9f..81c090f4c 100644
--- a/gnu/java/security/x509/ext/GeneralNames.java
+++ b/gnu/java/security/x509/ext/GeneralNames.java
@@ -1,5 +1,5 @@
/* GeneralNames.java -- the GeneralNames object
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -42,7 +42,6 @@ import gnu.java.security.OID;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
-import gnu.java.security.x509.X500DistinguishedName;
import java.io.IOException;
import java.net.InetAddress;
diff --git a/gnu/javax/crypto/assembly/Cascade.java b/gnu/javax/crypto/assembly/Cascade.java
index 678a7e730..a35d66886 100644
--- a/gnu/javax/crypto/assembly/Cascade.java
+++ b/gnu/javax/crypto/assembly/Cascade.java
@@ -60,7 +60,7 @@ import java.util.Set;
* of identical ciphers).</p>
*
* <p>The term "block ciphers" used above refers to implementations of
- * {@link gnu.crypto.mode.IMode}, including the {@link gnu.crypto.mode.ECB}
+ * {@link gnu.javax.crypto.mode.IMode}, including the {@link gnu.javax.crypto.mode.ECB}
* mode which basically exposes a symmetric-key block cipher algorithm as a
* <i>Mode</i> of Operations.</p>
*
diff --git a/gnu/javax/crypto/assembly/Direction.java b/gnu/javax/crypto/assembly/Direction.java
index 58b59a630..935b9618e 100644
--- a/gnu/javax/crypto/assembly/Direction.java
+++ b/gnu/javax/crypto/assembly/Direction.java
@@ -45,9 +45,9 @@ package gnu.javax.crypto.assembly;
*
* <p>The possible values for this type are two:</p>
* <ol>
- * <li>FORWARD: equivalent to {@link gnu.crypto.mode.IMode#ENCRYPTION}, and
+ * <li>FORWARD: equivalent to {@link gnu.javax.crypto.mode.IMode#ENCRYPTION}, and
* its inverse value</li>
- * <li>REVERSED: equivalent to {@link gnu.crypto.mode.IMode#DECRYPTION}.</li>
+ * <li>REVERSED: equivalent to {@link gnu.javax.crypto.mode.IMode#DECRYPTION}.</li>
* </ol>
*/
public final class Direction
diff --git a/gnu/javax/crypto/assembly/Transformer.java b/gnu/javax/crypto/assembly/Transformer.java
index 80430dc19..74a619af0 100644
--- a/gnu/javax/crypto/assembly/Transformer.java
+++ b/gnu/javax/crypto/assembly/Transformer.java
@@ -47,7 +47,7 @@ import java.util.Map;
* <p>A <code>Transformer</code> is an abstract representation of a two-way
* <i>transformation</i> that can be chained together with other instances of
* this type. Examples of such transformations in this library are:
- * {@link Cascade} cipher, {@link gnu.crypto.pad.IPad} algorithm, and a
+ * {@link Cascade} cipher, {@link gnu.javax.crypto.pad.IPad} algorithm, and a
* ZLib-based deflater/inflater algorithm. A special implementation of a
* <code>Transformer</code> to close a chain is also provided.</p>
*
diff --git a/gnu/javax/crypto/cipher/BaseCipher.java b/gnu/javax/crypto/cipher/BaseCipher.java
index 9d62311ed..f6d92994d 100644
--- a/gnu/javax/crypto/cipher/BaseCipher.java
+++ b/gnu/javax/crypto/cipher/BaseCipher.java
@@ -38,8 +38,6 @@ exception statement from your version. */
package gnu.javax.crypto.cipher;
-import gnu.java.security.util.Util;
-
import java.security.InvalidKeyException;
import java.util.Arrays;
import java.util.Iterator;
diff --git a/gnu/javax/crypto/cipher/IBlockCipherSpi.java b/gnu/javax/crypto/cipher/IBlockCipherSpi.java
index 6fe07ca7f..046f43f6f 100644
--- a/gnu/javax/crypto/cipher/IBlockCipherSpi.java
+++ b/gnu/javax/crypto/cipher/IBlockCipherSpi.java
@@ -43,7 +43,7 @@ import java.util.Iterator;
/**
* <p>Package-private interface exposing mandatory methods to be implemented by
- * concrete {@link gnu.crypto.cipher.BaseCipher} sub-classes.</p>
+ * concrete {@link gnu.javax.crypto.cipher.BaseCipher} sub-classes.</p>
*/
interface IBlockCipherSpi extends Cloneable
{
diff --git a/gnu/javax/crypto/jce/cipher/CipherAdapter.java b/gnu/javax/crypto/jce/cipher/CipherAdapter.java
index 5eaa31b77..f8adedce7 100644
--- a/gnu/javax/crypto/jce/cipher/CipherAdapter.java
+++ b/gnu/javax/crypto/jce/cipher/CipherAdapter.java
@@ -118,9 +118,9 @@ class CipherAdapter extends CipherSpi
/**
* <p>Protected constructor to be called by subclasses. The cipher name
- * argument should be the appropriate one listed in {@link gnu.crypto.Registry}.
+ * argument should be the appropriate one listed in {@link gnu.java.security.Registry}.
* The basic cipher instance is created, along with an instance of the
- * {@link gnu.crypto.mode.ECB} mode and no padding.</p>
+ * {@link gnu.javax.crypto.mode.ECB} mode and no padding.</p>
*
* @param cipherName The cipher to instantiate.
* @param blockLen The block length to use.
diff --git a/gnu/javax/crypto/jce/key/AnubisSecretKeyFactoryImpl.java b/gnu/javax/crypto/jce/key/AnubisSecretKeyFactoryImpl.java
index f9725eae0..6442cd696 100644
--- a/gnu/javax/crypto/jce/key/AnubisSecretKeyFactoryImpl.java
+++ b/gnu/javax/crypto/jce/key/AnubisSecretKeyFactoryImpl.java
@@ -38,13 +38,6 @@ exception statement from your version. */
package gnu.javax.crypto.jce.key;
-import java.security.InvalidKeyException;
-import java.security.spec.InvalidKeySpecException;
-
-import javax.crypto.SecretKey;
-import javax.crypto.SecretKeyFactorySpi;
-import javax.crypto.spec.SecretKeySpec;
-
public class AnubisSecretKeyFactoryImpl extends SecretKeyFactoryImpl
{
public AnubisSecretKeyFactoryImpl()
diff --git a/gnu/javax/crypto/jce/key/BlowfishSecretKeyFactoryImpl.java b/gnu/javax/crypto/jce/key/BlowfishSecretKeyFactoryImpl.java
index 4b3620bc1..91f97af36 100644
--- a/gnu/javax/crypto/jce/key/BlowfishSecretKeyFactoryImpl.java
+++ b/gnu/javax/crypto/jce/key/BlowfishSecretKeyFactoryImpl.java
@@ -38,13 +38,6 @@ exception statement from your version. */
package gnu.javax.crypto.jce.key;
-import java.security.InvalidKeyException;
-import java.security.spec.InvalidKeySpecException;
-
-import javax.crypto.SecretKey;
-import javax.crypto.SecretKeyFactorySpi;
-import javax.crypto.spec.SecretKeySpec;
-
public class BlowfishSecretKeyFactoryImpl extends SecretKeyFactoryImpl
{
public BlowfishSecretKeyFactoryImpl()
diff --git a/gnu/javax/crypto/jce/key/Cast5SecretKeyFactoryImpl.java b/gnu/javax/crypto/jce/key/Cast5SecretKeyFactoryImpl.java
index 4bd31711e..048b54474 100644
--- a/gnu/javax/crypto/jce/key/Cast5SecretKeyFactoryImpl.java
+++ b/gnu/javax/crypto/jce/key/Cast5SecretKeyFactoryImpl.java
@@ -38,13 +38,6 @@ exception statement from your version. */
package gnu.javax.crypto.jce.key;
-import java.security.InvalidKeyException;
-import java.security.spec.InvalidKeySpecException;
-
-import javax.crypto.SecretKey;
-import javax.crypto.SecretKeyFactorySpi;
-import javax.crypto.spec.SecretKeySpec;
-
public class Cast5SecretKeyFactoryImpl extends SecretKeyFactoryImpl
{
public Cast5SecretKeyFactoryImpl()
diff --git a/gnu/javax/crypto/jce/key/KhazadSecretKeyFactoryImpl.java b/gnu/javax/crypto/jce/key/KhazadSecretKeyFactoryImpl.java
index c86e01110..6c7ab42f7 100644
--- a/gnu/javax/crypto/jce/key/KhazadSecretKeyFactoryImpl.java
+++ b/gnu/javax/crypto/jce/key/KhazadSecretKeyFactoryImpl.java
@@ -37,13 +37,6 @@ exception statement from your version. */
package gnu.javax.crypto.jce.key;
-import java.security.InvalidKeyException;
-import java.security.spec.InvalidKeySpecException;
-
-import javax.crypto.SecretKey;
-import javax.crypto.SecretKeyFactorySpi;
-import javax.crypto.spec.SecretKeySpec;
-
public class KhazadSecretKeyFactoryImpl extends SecretKeyFactoryImpl
{
public KhazadSecretKeyFactoryImpl()
diff --git a/gnu/javax/crypto/jce/key/RijndaelSecretKeyFactoryImpl.java b/gnu/javax/crypto/jce/key/RijndaelSecretKeyFactoryImpl.java
index 4aab584a2..d46191644 100644
--- a/gnu/javax/crypto/jce/key/RijndaelSecretKeyFactoryImpl.java
+++ b/gnu/javax/crypto/jce/key/RijndaelSecretKeyFactoryImpl.java
@@ -37,13 +37,6 @@ exception statement from your version. */
package gnu.javax.crypto.jce.key;
-import java.security.InvalidKeyException;
-import java.security.spec.InvalidKeySpecException;
-
-import javax.crypto.SecretKey;
-import javax.crypto.SecretKeyFactorySpi;
-import javax.crypto.spec.SecretKeySpec;
-
public class RijndaelSecretKeyFactoryImpl extends SecretKeyFactoryImpl
{
public RijndaelSecretKeyFactoryImpl()
diff --git a/gnu/javax/crypto/jce/key/SerpentSecretKeyFactoryImpl.java b/gnu/javax/crypto/jce/key/SerpentSecretKeyFactoryImpl.java
index 6e80671fa..9f06bf329 100644
--- a/gnu/javax/crypto/jce/key/SerpentSecretKeyFactoryImpl.java
+++ b/gnu/javax/crypto/jce/key/SerpentSecretKeyFactoryImpl.java
@@ -37,13 +37,6 @@ exception statement from your version. */
package gnu.javax.crypto.jce.key;
-import java.security.InvalidKeyException;
-import java.security.spec.InvalidKeySpecException;
-
-import javax.crypto.SecretKey;
-import javax.crypto.SecretKeyFactorySpi;
-import javax.crypto.spec.SecretKeySpec;
-
public class SerpentSecretKeyFactoryImpl extends SecretKeyFactoryImpl
{
public SerpentSecretKeyFactoryImpl()
diff --git a/gnu/javax/crypto/jce/key/SquareSecretKeyFactoryImpl.java b/gnu/javax/crypto/jce/key/SquareSecretKeyFactoryImpl.java
index d1d5d5514..fce7375b3 100644
--- a/gnu/javax/crypto/jce/key/SquareSecretKeyFactoryImpl.java
+++ b/gnu/javax/crypto/jce/key/SquareSecretKeyFactoryImpl.java
@@ -37,13 +37,6 @@ exception statement from your version. */
package gnu.javax.crypto.jce.key;
-import java.security.InvalidKeyException;
-import java.security.spec.InvalidKeySpecException;
-
-import javax.crypto.SecretKey;
-import javax.crypto.SecretKeyFactorySpi;
-import javax.crypto.spec.SecretKeySpec;
-
public class SquareSecretKeyFactoryImpl extends SecretKeyFactoryImpl
{
public SquareSecretKeyFactoryImpl()
diff --git a/gnu/javax/crypto/jce/key/TwofishSecretKeyFactoryImpl.java b/gnu/javax/crypto/jce/key/TwofishSecretKeyFactoryImpl.java
index e6ca80b63..a182d4116 100644
--- a/gnu/javax/crypto/jce/key/TwofishSecretKeyFactoryImpl.java
+++ b/gnu/javax/crypto/jce/key/TwofishSecretKeyFactoryImpl.java
@@ -37,13 +37,6 @@ exception statement from your version. */
package gnu.javax.crypto.jce.key;
-import java.security.InvalidKeyException;
-import java.security.spec.InvalidKeySpecException;
-
-import javax.crypto.SecretKey;
-import javax.crypto.SecretKeyFactorySpi;
-import javax.crypto.spec.SecretKeySpec;
-
public class TwofishSecretKeyFactoryImpl extends SecretKeyFactoryImpl
{
public TwofishSecretKeyFactoryImpl()
diff --git a/gnu/javax/crypto/jce/keyring/GnuKeyring.java b/gnu/javax/crypto/jce/keyring/GnuKeyring.java
index d2501f893..5eeb2a306 100644
--- a/gnu/javax/crypto/jce/keyring/GnuKeyring.java
+++ b/gnu/javax/crypto/jce/keyring/GnuKeyring.java
@@ -90,30 +90,44 @@ public class GnuKeyring
public Enumeration engineAliases()
{
+ log.entering(this.getClass().getName(), "engineAliases");
ensureLoaded();
Enumeration result;
if (privateKR == null)
result = Collections.enumeration(Collections.EMPTY_SET);
- else
- {
- Set aliases = new HashSet();
- for (Enumeration e = privateKR.aliases(); e.hasMoreElements();)
- {
- String alias = (String) e.nextElement();
- if (alias != null)
- aliases.add(alias);
- }
-
- for (Enumeration e = publicKR.aliases(); e.hasMoreElements();)
- {
- String alias = (String) e.nextElement();
- if (alias != null)
- aliases.add(alias);
- }
-
- result = Collections.enumeration(aliases);
- }
-
+ else
+ {
+ Set aliases = new HashSet();
+ for (Enumeration e = privateKR.aliases(); e.hasMoreElements();)
+ {
+ String alias = (String) e.nextElement();
+ if (alias != null)
+ {
+ alias = alias.trim();
+ if (alias.length() > 0)
+ {
+ log.finest("Adding alias (from private keyring): " + alias);
+ aliases.add(alias);
+ }
+ }
+ }
+ for (Enumeration e = publicKR.aliases(); e.hasMoreElements();)
+ {
+ String alias = (String) e.nextElement();
+ if (alias != null)
+ {
+ alias = alias.trim();
+ if (alias.length() > 0)
+ {
+ log.finest("Adding alias (from public keyring): " + alias);
+ aliases.add(alias);
+ }
+ }
+ }
+ log.finest("Will enumerate: " + aliases);
+ result = Collections.enumeration(aliases);
+ }
+ log.exiting(this.getClass().getName(), "engineAliases");
return result;
}
@@ -181,13 +195,23 @@ public class GnuKeyring
}
public void engineSetCertificateEntry(String alias, Certificate cert)
+ throws KeyStoreException
{
log.entering(this.getClass().getName(), "engineSetCertificateEntry",
new Object[] { alias, cert });
-
ensureLoaded();
- publicKR.putCertificate(alias, cert);
+ if (privateKR.containsAlias(alias))
+ throw new KeyStoreException("Alias [" + alias
+ + "] already exists and DOES NOT identify a "
+ + "Trusted Certificate Entry");
+ if (publicKR.containsCertificate(alias))
+ {
+ log.fine("Public keyring already contains Alias [" + alias
+ + "]. Will remove it");
+ publicKR.remove(alias);
+ }
+ publicKR.putCertificate(alias, cert);
log.exiting(this.getClass().getName(), "engineSetCertificateEntry");
}
@@ -218,9 +242,7 @@ public class GnuKeyring
public Key engineGetKey(String alias, char[] password)
throws UnrecoverableKeyException
{
- log.entering(this.getClass().getName(), "engineGetKey",
- String.valueOf(password));
-
+ log.entering(this.getClass().getName(), "engineGetKey", alias);
ensureLoaded();
Key result = null;
if (password == null)
@@ -231,7 +253,8 @@ public class GnuKeyring
else if (privateKR.containsPrivateKey(alias))
result = privateKR.getPrivateKey(alias, password);
- log.exiting(this.getClass().getName(), "engineGetKey", result);
+ log.exiting(this.getClass().getName(), "engineGetKey",
+ result == null ? "null" : result.getClass().getName());
return result;
}
@@ -240,20 +263,28 @@ public class GnuKeyring
throws KeyStoreException
{
log.entering(this.getClass().getName(), "engineSetKeyEntry",
- new Object[] { alias, key, password, chain });
+ new Object[] { alias, key.getClass().getName(), chain });
ensureLoaded();
+ if (publicKR.containsAlias(alias))
+ throw new KeyStoreException("Alias [" + alias
+ + "] already exists and DOES NOT identify a "
+ + "Key Entry");
if (key instanceof PublicKey)
- privateKR.putPublicKey(alias, (PublicKey) key);
+ {
+ privateKR.remove(alias);
+ PublicKey pk = (PublicKey) key;
+ privateKR.putPublicKey(alias, pk);
+ }
else
{
if (! (key instanceof PrivateKey) && ! (key instanceof SecretKey))
throw new KeyStoreException("cannot store keys of type "
+ key.getClass().getName());
+ privateKR.remove(alias);
privateKR.putCertPath(alias, chain);
log.finest("About to put private key in keyring...");
privateKR.putPrivateKey(alias, key, password);
}
-
log.exiting(this.getClass().getName(), "engineSetKeyEntry");
}
@@ -292,7 +323,7 @@ public class GnuKeyring
public void engineLoad(InputStream in, char[] password) throws IOException
{
- log.entering(this.getClass().getName(), "engineLoad", String.valueOf(password));
+ log.entering(this.getClass().getName(), "engineLoad");
if (in != null)
{
if (! in.markSupported())
@@ -305,14 +336,12 @@ public class GnuKeyring
createNewKeyrings();
loaded = true;
-
log.exiting(this.getClass().getName(), "engineLoad");
}
public void engineStore(OutputStream out, char[] password) throws IOException
{
- log.entering(this.getClass().getName(), "engineStore", String.valueOf(password));
-
+ log.entering(this.getClass().getName(), "engineStore");
ensureLoaded();
HashMap attr = new HashMap();
attr.put(IKeyring.KEYRING_DATA_OUT, out);
@@ -320,14 +349,18 @@ public class GnuKeyring
privateKR.store(attr);
publicKR.store(attr);
-
log.exiting(this.getClass().getName(), "engineStore");
}
public int engineSize()
{
- ensureLoaded();
- return privateKR.size() + publicKR.size();
+ log.entering(this.getClass().getName(), "engineSize");
+ int result = 0;
+ for (Enumeration e = engineAliases(); e.hasMoreElements(); result++)
+ e.nextElement();
+
+ log.exiting(this.getClass().getName(), "engineSize", Integer.valueOf(result));
+ return result;
}
/**
diff --git a/gnu/javax/crypto/jce/mac/OMacImpl.java b/gnu/javax/crypto/jce/mac/OMacImpl.java
index f91902ae5..bf30d8e13 100644
--- a/gnu/javax/crypto/jce/mac/OMacImpl.java
+++ b/gnu/javax/crypto/jce/mac/OMacImpl.java
@@ -39,7 +39,6 @@ exception statement from your version. */
package gnu.javax.crypto.jce.mac;
import gnu.java.security.Registry;
-import javax.crypto.MacSpi;
public abstract class OMacImpl extends MacAdapter
{
diff --git a/gnu/javax/crypto/jce/prng/CSPRNGSpi.java b/gnu/javax/crypto/jce/prng/CSPRNGSpi.java
index c0aa015b0..acc0c8e84 100644
--- a/gnu/javax/crypto/jce/prng/CSPRNGSpi.java
+++ b/gnu/javax/crypto/jce/prng/CSPRNGSpi.java
@@ -38,10 +38,9 @@ exception statement from your version. */
package gnu.javax.crypto.jce.prng;
-import gnu.java.security.Registry;
-import gnu.javax.crypto.prng.CSPRNG;
import gnu.java.security.prng.IRandom;
import gnu.java.security.prng.LimitReachedException;
+import gnu.javax.crypto.prng.CSPRNG;
import java.net.MalformedURLException;
import java.security.SecureRandomSpi;
diff --git a/gnu/javax/crypto/jce/spec/TMMHParameterSpec.java b/gnu/javax/crypto/jce/spec/TMMHParameterSpec.java
index 0ebec0991..a3b5f26e8 100644
--- a/gnu/javax/crypto/jce/spec/TMMHParameterSpec.java
+++ b/gnu/javax/crypto/jce/spec/TMMHParameterSpec.java
@@ -45,7 +45,7 @@ import java.security.spec.AlgorithmParameterSpec;
/**
* This class represents the algorithm parameters for the Truncated
* Multi-Modular Hash function for use with JCE-derived instances of
- * {@link gnu.crypto.mac.TMMH16}.
+ * {@link gnu.javax.crypto.mac.TMMH16}.
*
* <p>This class is little more than a container for the key stream, tag
* length, and prefix parameters for the TMMH algorithm.
diff --git a/gnu/javax/crypto/key/dh/GnuDHPrivateKey.java b/gnu/javax/crypto/key/dh/GnuDHPrivateKey.java
index 0e71623b9..70b684b77 100644
--- a/gnu/javax/crypto/key/dh/GnuDHPrivateKey.java
+++ b/gnu/javax/crypto/key/dh/GnuDHPrivateKey.java
@@ -154,7 +154,7 @@ public class GnuDHPrivateKey extends GnuDHKey implements DHPrivateKey
* @return the byte sequence encoding this key according to the designated
* format.
* @exception IllegalArgumentException if the format is not supported.
- * @see gnu.crypto.key.dh.DHKeyPairRawCodec
+ * @see DHKeyPairRawCodec
*/
public byte[] getEncoded(int format)
{
diff --git a/gnu/javax/crypto/keyring/AuthenticatedEntry.java b/gnu/javax/crypto/keyring/AuthenticatedEntry.java
index 22b42b3ea..fa77c6ec6 100644
--- a/gnu/javax/crypto/keyring/AuthenticatedEntry.java
+++ b/gnu/javax/crypto/keyring/AuthenticatedEntry.java
@@ -38,25 +38,20 @@ exception statement from your version. */
package gnu.javax.crypto.keyring;
+import gnu.java.security.Registry;
+import gnu.javax.crypto.mac.IMac;
+import gnu.javax.crypto.mac.MacFactory;
+import gnu.javax.crypto.mac.MacOutputStream;
+
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
-
import java.security.InvalidKeyException;
-
import java.util.Arrays;
-import java.util.Date;
-import java.util.Iterator;
import java.util.HashMap;
-import java.util.List;
-
-import gnu.java.security.Registry;
-import gnu.javax.crypto.mac.IMac;
-import gnu.javax.crypto.mac.MacFactory;
-import gnu.javax.crypto.mac.MacInputStream;
-import gnu.javax.crypto.mac.MacOutputStream;
+import java.util.Iterator;
public final class AuthenticatedEntry extends MaskableEnvelopeEntry implements
Registry
diff --git a/gnu/javax/crypto/keyring/CertPathEntry.java b/gnu/javax/crypto/keyring/CertPathEntry.java
index ef62347ec..f9e523b2c 100644
--- a/gnu/javax/crypto/keyring/CertPathEntry.java
+++ b/gnu/javax/crypto/keyring/CertPathEntry.java
@@ -40,14 +40,11 @@ package gnu.javax.crypto.keyring;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
-import java.io.DataOutputStream;
import java.io.IOException;
-
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
-
import java.util.Date;
/**
diff --git a/gnu/javax/crypto/keyring/CertificateEntry.java b/gnu/javax/crypto/keyring/CertificateEntry.java
index 95a708ac5..67ac7bf4b 100644
--- a/gnu/javax/crypto/keyring/CertificateEntry.java
+++ b/gnu/javax/crypto/keyring/CertificateEntry.java
@@ -39,13 +39,11 @@ exception statement from your version. */
package gnu.javax.crypto.keyring;
import java.io.DataInputStream;
-import java.io.DataOutputStream;
import java.io.IOException;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
import java.util.Date;
/**
diff --git a/gnu/javax/crypto/keyring/EncryptedEntry.java b/gnu/javax/crypto/keyring/EncryptedEntry.java
index fad5f54b2..a47a3c6fa 100644
--- a/gnu/javax/crypto/keyring/EncryptedEntry.java
+++ b/gnu/javax/crypto/keyring/EncryptedEntry.java
@@ -38,21 +38,6 @@ exception statement from your version. */
package gnu.javax.crypto.keyring;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-
-import java.security.InvalidKeyException;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.HashMap;
-import java.util.List;
-
import gnu.java.security.Registry;
import gnu.javax.crypto.cipher.CipherFactory;
import gnu.javax.crypto.cipher.IBlockCipher;
@@ -62,6 +47,15 @@ import gnu.javax.crypto.pad.IPad;
import gnu.javax.crypto.pad.PadFactory;
import gnu.javax.crypto.pad.WrongPaddingException;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.util.HashMap;
+import java.util.Iterator;
+
public class EncryptedEntry extends MaskableEnvelopeEntry implements Registry
{
diff --git a/gnu/javax/crypto/keyring/Entry.java b/gnu/javax/crypto/keyring/Entry.java
index fa7f49679..2f311271a 100644
--- a/gnu/javax/crypto/keyring/Entry.java
+++ b/gnu/javax/crypto/keyring/Entry.java
@@ -41,16 +41,23 @@ package gnu.javax.crypto.keyring;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
+import java.util.logging.Logger;
/**
* An immutable class representing a single entry in a keyring.
*/
public abstract class Entry
{
-
// Fields.
// ------------------------------------------------------------------------
+ private static final Logger log = Logger.getLogger(Entry.class.getName());
+ private static final String[] TYPES = new String[]
+ {
+ "Encrypted", "PasswordEncrypted", "Authenticated", "PasswordAuthenticated",
+ "Compressed", "Certificate", "PublicKey", "PrivateKey", "CertPath",
+ "BinaryData"
+ };
/** This entry's type identifier. */
protected int type;
@@ -145,6 +152,17 @@ public abstract class Entry
out.write(payload);
}
+ public String toString()
+ {
+
+ return new StringBuilder("Entry{")
+ .append("type=").append(TYPES[type])
+ .append(", properties=").append(properties)
+ .append(", payload=")
+ .append(payload == null? "-" : "byte[" + payload.length + "]")
+ .append("}").toString();
+ }
+
/**
* Generic decoding method, which simply decodes the properties field
* and reads the payload field.
@@ -161,6 +179,7 @@ public abstract class Entry
{
throw new IOException("corrupt length");
}
+ log.finest("About to instantiate new payload byte array for " + this);
payload = new byte[len];
in.readFully(payload);
}
diff --git a/gnu/javax/crypto/keyring/EnvelopeEntry.java b/gnu/javax/crypto/keyring/EnvelopeEntry.java
index 25b1dc2a0..2a57a23da 100644
--- a/gnu/javax/crypto/keyring/EnvelopeEntry.java
+++ b/gnu/javax/crypto/keyring/EnvelopeEntry.java
@@ -42,13 +42,12 @@ import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
-
import java.util.ArrayList;
-import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;
+import java.util.logging.Logger;
/**
* An envelope entry is a generic container for some number of primitive
@@ -56,10 +55,10 @@ import java.util.StringTokenizer;
*/
public abstract class EnvelopeEntry extends Entry
{
-
// Fields.
// ------------------------------------------------------------------------
+ private static final Logger log = Logger.getLogger(EnvelopeEntry.class.getName());
/** The envelope that contains this one (if any). */
protected EnvelopeEntry containingEnvelope;
@@ -95,16 +94,17 @@ public abstract class EnvelopeEntry extends Entry
*/
public void add(Entry entry)
{
- if (!containsEntry(entry))
+ log.entering(this.getClass().getName(), "add", entry);
+ if (! containsEntry(entry))
{
if (entry instanceof EnvelopeEntry)
- {
- ((EnvelopeEntry) entry).setContainingEnvelope(this);
- }
+ ((EnvelopeEntry) entry).setContainingEnvelope(this);
+
entries.add(entry);
- payload = null;
+ log.finest("Payload is " + (payload == null ? "" : "not ") + "null");
makeAliasList();
}
+ log.exiting(this.getClass().getName(), "add");
}
/**
@@ -117,20 +117,22 @@ public abstract class EnvelopeEntry extends Entry
*/
public boolean containsAlias(String alias)
{
+ log.entering(this.getClass().getName(), "containsAlias", alias);
String aliases = getAliasList();
- if (aliases == null)
- {
- return false;
- }
- StringTokenizer tok = new StringTokenizer(aliases, ";");
- while (tok.hasMoreTokens())
+ log.finest("aliases = [" + aliases + "]");
+ boolean result = false;
+ if (aliases != null)
{
- if (tok.nextToken().equals(alias))
- {
- return true;
- }
+ StringTokenizer tok = new StringTokenizer(aliases, ";");
+ while (tok.hasMoreTokens())
+ if (tok.nextToken().equals(alias))
+ {
+ result = true;
+ break;
+ }
}
- return false;
+ log.exiting(this.getClass().getName(), "containsAlias", Boolean.valueOf(result));
+ return result;
}
/**
@@ -180,34 +182,41 @@ public abstract class EnvelopeEntry extends Entry
*/
public List get(String alias)
{
+ log.entering(this.getClass().getName(), "get", alias);
+
List result = new LinkedList();
for (Iterator it = entries.iterator(); it.hasNext();)
{
Entry e = (Entry) it.next();
if (e instanceof EnvelopeEntry)
{
- if (!((EnvelopeEntry) e).containsAlias(alias))
- {
- continue;
- }
- if (e instanceof MaskableEnvelopeEntry)
+ EnvelopeEntry ee = (EnvelopeEntry) e;
+ if (! ee.containsAlias(alias))
+ continue;
+
+ if (ee instanceof MaskableEnvelopeEntry)
{
- if (((MaskableEnvelopeEntry) e).isMasked())
+ MaskableEnvelopeEntry mee = (MaskableEnvelopeEntry) ee;
+ if (mee.isMasked())
{
- result.add(e);
+ log.finer("Processing masked entry: " + mee);
+ result.add(mee);
continue;
}
}
- result.addAll(((EnvelopeEntry) e).get(alias));
+
+ log.finer("Processing unmasked entry: " + ee);
+ result.addAll(ee.get(alias));
}
else if (e instanceof PrimitiveEntry)
{
- if (((PrimitiveEntry) e).getAlias().equals(alias))
- {
- result.add(e);
- }
+ PrimitiveEntry pe = (PrimitiveEntry) e;
+ if (pe.getAlias().equals(alias))
+ result.add(e);
}
}
+
+ log.exiting(this.getClass().getName(), "get", result);
return result;
}
@@ -238,6 +247,7 @@ public abstract class EnvelopeEntry extends Entry
*/
public boolean remove(Entry entry)
{
+ log.entering(this.getClass().getName(), "remove", entry);
boolean ret = false;
for (Iterator it = entries.iterator(); it.hasNext();)
{
@@ -268,36 +278,63 @@ public abstract class EnvelopeEntry extends Entry
}
if (ret)
{
+ log.finest("State before: " + this);
payload = null;
makeAliasList();
+ log.finest("State after: " + this);
}
+ log.exiting(this.getClass().getName(), "remove", Boolean.valueOf(ret));
return ret;
}
/**
* Removes all primitive entries that have the specified alias.
- *
+ *
* @param alias The alias of the entries to remove.
+ * @return <code>true</code> if <code>alias</code> was present and was
+ * successfully trmoved. Returns <code>false</code> if
+ * <code>alias</code> was not present in the list of aliases in this
+ * envelope.
*/
- public void remove(String alias)
+ public boolean remove(String alias)
{
+ log.entering(this.getClass().getName(), "remove", alias);
+ boolean result = false;
for (Iterator it = entries.iterator(); it.hasNext();)
{
Entry e = (Entry) it.next();
if (e instanceof EnvelopeEntry)
{
- ((EnvelopeEntry) e).remove(alias);
+ EnvelopeEntry ee = (EnvelopeEntry) e;
+ result = ee.remove(alias) || result;
}
else if (e instanceof PrimitiveEntry)
{
- if (((PrimitiveEntry) e).getAlias().equals(alias))
+ PrimitiveEntry pe = (PrimitiveEntry) e;
+ if (pe.getAlias().equals(alias))
{
it.remove();
+ result = true;
}
}
}
- payload = null;
- makeAliasList();
+ if (result)
+ {
+ log.finest("State before: " + this);
+ payload = null;
+ makeAliasList();
+ log.finest("State after: " + this);
+ }
+ log.exiting(this.getClass().getName(), "remove", Boolean.valueOf(result));
+ return result;
+ }
+
+ public String toString()
+ {
+ return new StringBuilder("Envelope{")
+ .append(super.toString())
+ .append(", entries=").append(entries)
+ .append("}").toString();
}
// Protected methods.
@@ -324,6 +361,7 @@ public abstract class EnvelopeEntry extends Entry
protected void decodeEnvelope(DataInputStream in) throws IOException
{
+ this.entries.clear();
while (true)
{
int type = in.read();
@@ -372,27 +410,39 @@ public abstract class EnvelopeEntry extends Entry
private void makeAliasList()
{
- if (entries.isEmpty())
- return;
- StringBuffer buf = new StringBuffer();
- for (Iterator it = entries.iterator(); it.hasNext();)
+ log.entering(this.getClass().getName(), "makeAliasList");
+ if (! entries.isEmpty())
{
- Entry entry = (Entry) it.next();
- if (entry instanceof EnvelopeEntry)
- {
- buf.append(((EnvelopeEntry) entry).getAliasList());
- }
- else if (entry instanceof PrimitiveEntry)
+ StringBuilder buf = new StringBuilder();
+ String aliasOrList;
+ for (Iterator it = entries.iterator(); it.hasNext();)
{
- buf.append(((PrimitiveEntry) entry).getAlias());
+ Entry entry = (Entry) it.next();
+ aliasOrList = null;
+ if (entry instanceof EnvelopeEntry)
+ aliasOrList = ((EnvelopeEntry) entry).getAliasList();
+ else if (entry instanceof PrimitiveEntry)
+ aliasOrList = ((PrimitiveEntry) entry).getAlias();
+ else
+ log.fine("Entry with no Alias. Ignored: " + entry);
+
+ if (aliasOrList != null)
+ {
+ aliasOrList = aliasOrList.trim();
+ if (aliasOrList.trim().length() > 0)
+ {
+ buf.append(aliasOrList);
+ if (it.hasNext())
+ buf.append(';');
+ }
+ }
}
- if (it.hasNext())
- buf.append(';');
- }
- properties.put("alias-list", buf.toString());
- if (containingEnvelope != null)
- {
- containingEnvelope.makeAliasList();
+ String aliasList = buf.toString();
+ properties.put("alias-list", aliasList);
+ log.finer("alias-list=[" + aliasList + "]");
+ if (containingEnvelope != null)
+ containingEnvelope.makeAliasList();
}
+ log.exiting(this.getClass().getName(), "makeAliasList");
}
}
diff --git a/gnu/javax/crypto/keyring/GnuPrivateKeyring.java b/gnu/javax/crypto/keyring/GnuPrivateKeyring.java
index c1fe30e67..bd5a96227 100644
--- a/gnu/javax/crypto/keyring/GnuPrivateKeyring.java
+++ b/gnu/javax/crypto/keyring/GnuPrivateKeyring.java
@@ -106,7 +106,6 @@ public class GnuPrivateKeyring extends BaseKeyring implements IPrivateKeyring
public boolean containsPrivateKey(String alias)
{
log.entering(this.getClass().getName(), "containsPrivateKey", alias);
-
boolean result = false;
if (containsAlias(alias))
for (Iterator it = get(alias).iterator(); it.hasNext();)
@@ -115,7 +114,6 @@ public class GnuPrivateKeyring extends BaseKeyring implements IPrivateKeyring
result = true;
break;
}
-
log.exiting(this.getClass().getName(), "containsPrivateKey",
Boolean.valueOf(result));
return result;
@@ -124,17 +122,15 @@ public class GnuPrivateKeyring extends BaseKeyring implements IPrivateKeyring
public Key getPrivateKey(String alias, char[] password)
throws UnrecoverableKeyException
{
- log.entering(this.getClass().getName(), "getPrivateKey",
- new Object[] { alias, String.valueOf(password) });
-
+ log.entering(this.getClass().getName(), "getPrivateKey", alias);
Key result = null;
if (containsAlias(alias))
{
PasswordAuthenticatedEntry e1 = null;
- PasswordEncryptedEntry e2 = null;
for (Iterator it = get(alias).iterator(); it.hasNext();)
{
Entry e = (Entry) it.next();
+ log.finest("Entry: " + e);
if (e instanceof PasswordAuthenticatedEntry)
{
e1 = (PasswordAuthenticatedEntry) e;
@@ -142,6 +138,7 @@ public class GnuPrivateKeyring extends BaseKeyring implements IPrivateKeyring
}
}
+ log.finest("e1 = " + e1);
if (e1 != null)
{
try
@@ -150,9 +147,11 @@ public class GnuPrivateKeyring extends BaseKeyring implements IPrivateKeyring
}
catch (Exception e)
{
+ log.throwing(this.getClass().getName(), "getPrivateKey", e);
throw new UnrecoverableKeyException("authentication failed");
}
+ PasswordEncryptedEntry e2 = null;
for (Iterator it = e1.getEntries().iterator(); it.hasNext();)
{
Entry e = (Entry) it.next();
@@ -171,6 +170,7 @@ public class GnuPrivateKeyring extends BaseKeyring implements IPrivateKeyring
}
catch (Exception e)
{
+ log.throwing(this.getClass().getName(), "getPrivateKey", e);
throw new UnrecoverableKeyException("decryption failed");
}
@@ -186,31 +186,26 @@ public class GnuPrivateKeyring extends BaseKeyring implements IPrivateKeyring
}
}
}
-
- log.exiting(this.getClass().getName(), "getPrivateKey", result);
+ log.exiting(this.getClass().getName(), "getPrivateKey",
+ result == null ? "null" : result.getClass().getName());
return result;
}
public void putPrivateKey(String alias, Key key, char[] password)
{
log.entering(this.getClass().getName(), "putPrivateKey",
- new Object[] { alias, key, String.valueOf(password) });
-
+ new Object[] { alias, key.getClass().getName() });
if (! containsPrivateKey(alias))
{
alias = fixAlias(alias);
Properties p = new Properties();
p.put("alias", alias);
PrivateKeyEntry pke = new PrivateKeyEntry(key, new Date(), p);
+
+ log.finest("About to encrypt the key...");
PasswordEncryptedEntry enc;
enc = new PasswordEncryptedEntry(cipher, mode, keylen, new Properties());
enc.add(pke);
-
- PasswordAuthenticatedEntry auth;
- auth = new PasswordAuthenticatedEntry(mac, maclen, new Properties());
- auth.add(enc);
-
- log.finest("About to encrypt the key...");
try
{
enc.encode(null, password);
@@ -218,11 +213,14 @@ public class GnuPrivateKeyring extends BaseKeyring implements IPrivateKeyring
catch (IOException x)
{
log.log(Level.FINER, "Exception while encrypting the key. "
- + "Rethrow as IllegalArgumentException", x);
+ + "Rethrow as IllegalArgumentException", x);
throw new IllegalArgumentException(x.toString());
}
log.finest("About to authenticate the encrypted key...");
+ PasswordAuthenticatedEntry auth;
+ auth = new PasswordAuthenticatedEntry(mac, maclen, new Properties());
+ auth.add(enc);
try
{
auth.encode(null, password);
@@ -230,7 +228,7 @@ public class GnuPrivateKeyring extends BaseKeyring implements IPrivateKeyring
catch (IOException x)
{
log.log(Level.FINER, "Exception while authenticating the encrypted "
- + "key. Rethrow as IllegalArgumentException", x);
+ + "key. Rethrow as IllegalArgumentException", x);
throw new IllegalArgumentException(x.toString());
}
@@ -245,7 +243,6 @@ public class GnuPrivateKeyring extends BaseKeyring implements IPrivateKeyring
public boolean containsPublicKey(String alias)
{
log.entering(this.getClass().getName(), "containsPublicKey", alias);
-
boolean result = false;
if (containsAlias(alias))
for (Iterator it = get(alias).iterator(); it.hasNext();)
@@ -254,7 +251,6 @@ public class GnuPrivateKeyring extends BaseKeyring implements IPrivateKeyring
result = true;
break;
}
-
log.exiting(this.getClass().getName(), "containsPublicKey",
Boolean.valueOf(result));
return result;
@@ -263,7 +259,6 @@ public class GnuPrivateKeyring extends BaseKeyring implements IPrivateKeyring
public PublicKey getPublicKey(String alias)
{
log.entering(this.getClass().getName(), "getPublicKey", alias);
-
PublicKey result = null;
if (containsAlias(alias))
for (Iterator it = get(alias).iterator(); it.hasNext();)
@@ -275,16 +270,15 @@ public class GnuPrivateKeyring extends BaseKeyring implements IPrivateKeyring
break;
}
}
-
- log.exiting(this.getClass().getName(), "getPublicKey", result);
+ log.exiting(this.getClass().getName(), "getPublicKey",
+ result == null ? "null" : result.getClass().getName());
return result;
}
public void putPublicKey(String alias, PublicKey key)
{
log.entering(this.getClass().getName(), "putPublicKey",
- new Object[] { alias, key });
-
+ new Object[] { alias, key.getClass().getName() });
if (! containsPublicKey(alias))
{
Properties p = new Properties();
@@ -300,7 +294,6 @@ public class GnuPrivateKeyring extends BaseKeyring implements IPrivateKeyring
public boolean containsCertPath(String alias)
{
log.entering(this.getClass().getName(), "containsCertPath", alias);
-
boolean result = false;
if (containsAlias(alias))
for (Iterator it = get(alias).iterator(); it.hasNext();)
@@ -309,7 +302,6 @@ public class GnuPrivateKeyring extends BaseKeyring implements IPrivateKeyring
result = true;
break;
}
-
log.exiting(this.getClass().getName(), "containsCertPath",
Boolean.valueOf(result));
return result;
@@ -318,7 +310,6 @@ public class GnuPrivateKeyring extends BaseKeyring implements IPrivateKeyring
public Certificate[] getCertPath(String alias)
{
log.entering(this.getClass().getName(), "getCertPath", alias);
-
Certificate[] result = null;
if (containsAlias(alias))
for (Iterator it = get(alias).iterator(); it.hasNext();)
@@ -330,7 +321,6 @@ public class GnuPrivateKeyring extends BaseKeyring implements IPrivateKeyring
break;
}
}
-
log.exiting(this.getClass().getName(), "getCertPath", result);
return result;
}
@@ -339,7 +329,6 @@ public class GnuPrivateKeyring extends BaseKeyring implements IPrivateKeyring
{
log.entering(this.getClass().getName(), "putCertPath",
new Object[] { alias, path });
-
if (! containsCertPath(alias))
{
Properties p = new Properties();
@@ -354,28 +343,23 @@ public class GnuPrivateKeyring extends BaseKeyring implements IPrivateKeyring
protected void load(InputStream in, char[] password) throws IOException
{
- log.entering(this.getClass().getName(), "load",
- new Object[] { in, String.valueOf(password) });
-
+ log.entering(this.getClass().getName(), "load");
if (in.read() != USAGE)
throw new MalformedKeyringException("incompatible keyring usage");
if (in.read() != PasswordAuthenticatedEntry.TYPE)
throw new MalformedKeyringException("expecting password-authenticated entry tag");
- keyring = PasswordAuthenticatedEntry.decode(new DataInputStream(in), password);
-
+ keyring = PasswordAuthenticatedEntry.decode(new DataInputStream(in),
+ password);
log.exiting(this.getClass().getName(), "load");
}
protected void store(OutputStream out, char[] password) throws IOException
{
- log.entering(this.getClass().getName(), "store",
- new Object[] { out, String.valueOf(password) });
-
+ log.entering(this.getClass().getName(), "store");
out.write(USAGE);
keyring.encode(new DataOutputStream(out), password);
-
log.exiting(this.getClass().getName(), "store");
}
}
diff --git a/gnu/javax/crypto/keyring/GnuPublicKeyring.java b/gnu/javax/crypto/keyring/GnuPublicKeyring.java
index 490eb4458..7e1182bc1 100644
--- a/gnu/javax/crypto/keyring/GnuPublicKeyring.java
+++ b/gnu/javax/crypto/keyring/GnuPublicKeyring.java
@@ -78,7 +78,6 @@ public class GnuPublicKeyring extends BaseKeyring implements IPublicKeyring
public boolean containsCertificate(String alias)
{
log.entering(this.getClass().getName(), "containsCertificate", alias);
-
boolean result = false;
if (containsAlias(alias))
for (Iterator it = get(alias).iterator(); it.hasNext();)
@@ -87,7 +86,6 @@ public class GnuPublicKeyring extends BaseKeyring implements IPublicKeyring
result = true;
break;
}
-
log.exiting(this.getClass().getName(), "containsCertificate",
Boolean.valueOf(result));
return result;
@@ -96,7 +94,6 @@ public class GnuPublicKeyring extends BaseKeyring implements IPublicKeyring
public Certificate getCertificate(String alias)
{
log.entering(this.getClass().getName(), "getCertificate", alias);
-
Certificate result = null;
if (containsAlias(alias))
for (Iterator it = get(alias).iterator(); it.hasNext();)
@@ -108,7 +105,6 @@ public class GnuPublicKeyring extends BaseKeyring implements IPublicKeyring
break;
}
}
-
log.exiting(this.getClass().getName(), "getCertificate", result);
return result;
}
@@ -117,7 +113,6 @@ public class GnuPublicKeyring extends BaseKeyring implements IPublicKeyring
{
log.entering(this.getClass().getName(), "putCertificate",
new Object[] { alias, cert });
-
if (! containsCertificate(alias))
{
Properties p = new Properties();
@@ -132,9 +127,7 @@ public class GnuPublicKeyring extends BaseKeyring implements IPublicKeyring
protected void load(InputStream in, char[] password) throws IOException
{
- log.entering(this.getClass().getName(), "load",
- new Object[] { in, String.valueOf(password) });
-
+ log.entering(this.getClass().getName(), "load");
if (in.read() != USAGE)
throw new MalformedKeyringException("incompatible keyring usage");
@@ -143,18 +136,14 @@ public class GnuPublicKeyring extends BaseKeyring implements IPublicKeyring
DataInputStream dis = new DataInputStream(in);
keyring = PasswordAuthenticatedEntry.decode(dis, password);
-
log.exiting(this.getClass().getName(), "load");
}
protected void store(OutputStream out, char[] password) throws IOException
{
- log.entering(this.getClass().getName(), "store",
- new Object[] { out, String.valueOf(password) });
-
+ log.entering(this.getClass().getName(), "store");
out.write(USAGE);
keyring.encode(new DataOutputStream(out), password);
-
log.exiting(this.getClass().getName(), "store");
}
}
diff --git a/gnu/javax/crypto/keyring/MaskableEnvelopeEntry.java b/gnu/javax/crypto/keyring/MaskableEnvelopeEntry.java
index 7fed7c40c..653d62ced 100644
--- a/gnu/javax/crypto/keyring/MaskableEnvelopeEntry.java
+++ b/gnu/javax/crypto/keyring/MaskableEnvelopeEntry.java
@@ -48,7 +48,6 @@ import java.util.List;
*/
public abstract class MaskableEnvelopeEntry extends EnvelopeEntry
{
-
// Fields.
// ------------------------------------------------------------------------
@@ -137,12 +136,19 @@ public abstract class MaskableEnvelopeEntry extends EnvelopeEntry
return super.remove(entry);
}
- public void remove(String alias)
+ public boolean remove(String alias)
{
if (isMasked())
- {
- throw new IllegalStateException("masked envelope");
- }
- super.remove(alias);
+ throw new IllegalStateException("masked envelope");
+
+ return super.remove(alias);
+ }
+
+ public String toString()
+ {
+ return new StringBuilder("MaskableEnvelope{")
+ .append(super.toString())
+ .append(", masked=").append(masked)
+ .append("}").toString();
}
}
diff --git a/gnu/javax/crypto/keyring/PasswordAuthenticatedEntry.java b/gnu/javax/crypto/keyring/PasswordAuthenticatedEntry.java
index 4e7e49a0b..96d4fc4db 100644
--- a/gnu/javax/crypto/keyring/PasswordAuthenticatedEntry.java
+++ b/gnu/javax/crypto/keyring/PasswordAuthenticatedEntry.java
@@ -146,11 +146,11 @@ public final class PasswordAuthenticatedEntry extends MaskableEnvelopeEntry
public void verify(char[] password)
{
- log.entering(this.getClass().getName(), "verify", String.valueOf(password));
- long tt = - System.currentTimeMillis();
-
+ log.entering(this.getClass().getName(), "verify");
if (isMasked() && payload != null)
{
+ log.finest("payload to verify: " + Util.dumpString(payload));
+ long tt = - System.currentTimeMillis();
IMac m = null;
try
{
@@ -169,6 +169,8 @@ public final class PasswordAuthenticatedEntry extends MaskableEnvelopeEntry
if (! Arrays.equals(macValue, m.digest()))
throw new IllegalArgumentException("MAC verification failed");
+ setMasked(false);
+
ByteArrayInputStream bais;
try
{
@@ -180,19 +182,18 @@ public final class PasswordAuthenticatedEntry extends MaskableEnvelopeEntry
{
throw new IllegalArgumentException("malformed keyring fragment");
}
- setMasked(false);
- payload = null;
- }
- tt += System.currentTimeMillis();
- log.finer("Verified in " + tt + "ms.");
+ tt += System.currentTimeMillis();
+ log.finer("Verified in " + tt + "ms.");
+ }
+ else
+ log.finer("Skip verification; " + (isMasked() ? "null payload" : "unmasked"));
log.exiting(this.getClass().getName(), "verify");
}
public void authenticate(char[] password) throws IOException
{
- log.entering(this.getClass().getName(), "authenticate",
- String.valueOf(password));
+ log.entering(this.getClass().getName(), "authenticate");
long tt = - System.currentTimeMillis();
long t1 = - System.currentTimeMillis();
@@ -218,7 +219,10 @@ public final class PasswordAuthenticatedEntry extends MaskableEnvelopeEntry
log.finer("-- Authenticated an Entry in " + t1 + "ms.");
}
bout.write(m.digest());
+
payload = bout.toByteArray();
+ log.finest("authenticated payload: " + Util.dumpString(payload));
+ setMasked(true);
tt += System.currentTimeMillis();
log.finer("Authenticated in " + tt + "ms.");
@@ -235,6 +239,7 @@ public final class PasswordAuthenticatedEntry extends MaskableEnvelopeEntry
{
if (payload == null)
{
+ log.fine("Null payload: " + this);
throw new IllegalStateException("mac not computed");
}
}
@@ -244,26 +249,25 @@ public final class PasswordAuthenticatedEntry extends MaskableEnvelopeEntry
private IMac getMac(char[] password) throws MalformedKeyringException
{
- if (!properties.containsKey("salt"))
- {
- throw new MalformedKeyringException("no salt");
- }
- byte[] salt = Util.toBytesFromString(properties.get("salt"));
- IMac mac = MacFactory.getInstance(properties.get("mac"));
+ log.entering(this.getClass().getName(), "getMac");
+ String saltString = properties.get("salt");
+ if (saltString == null)
+ throw new MalformedKeyringException("no salt");
+
+ byte[] salt = Util.toBytesFromString(saltString);
+ String macAlgorithm = properties.get("mac");
+ IMac mac = MacFactory.getInstance(macAlgorithm);
if (mac == null)
- {
- throw new MalformedKeyringException("no such mac: "
- + properties.get("mac"));
- }
- int keylen = mac.macSize();
- int maclen = 0;
- if (!properties.containsKey("maclen"))
- {
- throw new MalformedKeyringException("no MAC length");
- }
+ throw new MalformedKeyringException("no such mac: " + macAlgorithm);
+
+ String macLenString = properties.get("maclen");
+ if (macLenString == null)
+ throw new MalformedKeyringException("no MAC length");
+
+ int maclen;
try
{
- maclen = Integer.parseInt(properties.get("maclen"));
+ maclen = Integer.parseInt(macLenString);
}
catch (NumberFormatException nfe)
{
@@ -277,6 +281,7 @@ public final class PasswordAuthenticatedEntry extends MaskableEnvelopeEntry
IRandom kdf = PRNGFactory.getInstance("PBKDF2-HMAC-SHA");
kdf.init(pbAttr);
+ int keylen = mac.macSize();
byte[] dk = new byte[keylen];
try
{
@@ -298,6 +303,7 @@ public final class PasswordAuthenticatedEntry extends MaskableEnvelopeEntry
{
throw new Error(shouldNotHappen.toString());
}
+ log.exiting(this.getClass().getName(), "getMac");
return mac;
}
}
diff --git a/gnu/javax/crypto/keyring/PasswordEncryptedEntry.java b/gnu/javax/crypto/keyring/PasswordEncryptedEntry.java
index d67ef0e0a..24ab98266 100644
--- a/gnu/javax/crypto/keyring/PasswordEncryptedEntry.java
+++ b/gnu/javax/crypto/keyring/PasswordEncryptedEntry.java
@@ -132,39 +132,40 @@ public class PasswordEncryptedEntry extends MaskableEnvelopeEntry implements
public void decrypt(char[] password) throws IllegalArgumentException,
WrongPaddingException
{
- log.entering(this.getClass().getName(), "decrypt", String.valueOf(password));
- long tt = - System.currentTimeMillis();
+ log.entering(this.getClass().getName(), "decrypt");
+ if (isMasked() && payload != null)
+ {
+ long tt = - System.currentTimeMillis();
+ IMode mode = getMode(password, IMode.DECRYPTION);
+ IPad padding = PadFactory.getInstance("PKCS7");
+ padding.init(mode.currentBlockSize());
+ byte[] buf = new byte[payload.length];
+ int count = 0;
+ while (count + mode.currentBlockSize() <= payload.length)
+ {
+ mode.update(payload, count, buf, count);
+ count += mode.currentBlockSize();
+ }
+ int padlen = padding.unpad(buf, 0, buf.length);
- if (!isMasked() || payload == null)
- return;
+ setMasked(false);
- IMode mode = getMode(password, IMode.DECRYPTION);
- IPad padding = PadFactory.getInstance("PKCS7");
- padding.init(mode.currentBlockSize());
- byte[] buf = new byte[payload.length];
- int count = 0;
- for (int i = 0; i < payload.length; i++)
- {
- mode.update(payload, count, buf, count);
- count += mode.currentBlockSize();
- }
- int padlen = padding.unpad(buf, 0, buf.length);
- ByteArrayInputStream baos = new ByteArrayInputStream(buf, 0,
- buf.length - padlen);
- DataInputStream in = new DataInputStream(baos);
- try
- {
- decodeEnvelope(in);
- }
- catch (IOException ioe)
- {
- throw new IllegalArgumentException("decryption failed");
+ ByteArrayInputStream baos = new ByteArrayInputStream(buf, 0,
+ buf.length - padlen);
+ DataInputStream in = new DataInputStream(baos);
+ try
+ {
+ decodeEnvelope(in);
+ }
+ catch (IOException ioe)
+ {
+ throw new IllegalArgumentException("decryption failed");
+ }
+ tt += System.currentTimeMillis();
+ log.finer("Decrypted in " + tt + "ms.");
}
- setMasked(false);
- payload = null;
-
- tt += System.currentTimeMillis();
- log.finer("Decrypted in " + tt + "ms.");
+ else
+ log.finer("Skip decryption; " + (isMasked() ? "null payload" : "unmasked"));
log.exiting(this.getClass().getName(), "decrypt");
}
@@ -208,6 +209,8 @@ public class PasswordEncryptedEntry extends MaskableEnvelopeEntry implements
}
mode.update(lastBlock, 0, payload, count);
+ setMasked(true);
+
tt += System.currentTimeMillis();
log.finer("Encrypted in " + tt + "ms.");
log.exiting(this.getClass().getName(), "encrypt");
@@ -223,6 +226,7 @@ public class PasswordEncryptedEntry extends MaskableEnvelopeEntry implements
{
if (payload == null)
{
+ log.fine("Null payload: " + this);
throw new IllegalStateException("not encrypted");
}
}
diff --git a/gnu/javax/crypto/keyring/PrivateKeyEntry.java b/gnu/javax/crypto/keyring/PrivateKeyEntry.java
index 882495633..cf5b41287 100644
--- a/gnu/javax/crypto/keyring/PrivateKeyEntry.java
+++ b/gnu/javax/crypto/keyring/PrivateKeyEntry.java
@@ -42,12 +42,10 @@ import gnu.java.security.key.IKeyPairCodec;
import gnu.java.security.key.KeyPairCodecFactory;
import gnu.java.security.key.dss.DSSPrivateKey;
import gnu.java.security.key.rsa.GnuRSAPrivateKey;
-
import gnu.javax.crypto.key.GnuSecretKey;
import gnu.javax.crypto.key.dh.GnuDHPrivateKey;
import java.io.DataInputStream;
-import java.io.DataOutputStream;
import java.io.IOException;
import java.security.Key;
import java.security.KeyFactory;
@@ -56,11 +54,11 @@ import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Date;
/**
- * <p>An immutable class representing a private or secret key entry.</p>
+ * An immutable class representing a private or secret key entry.
*/
-public final class PrivateKeyEntry extends PrimitiveEntry
+public final class PrivateKeyEntry
+ extends PrimitiveEntry
{
-
// Constants and variables
// -------------------------------------------------------------------------
@@ -73,7 +71,7 @@ public final class PrivateKeyEntry extends PrimitiveEntry
// -------------------------------------------------------------------------
/**
- * <p>Creates a new key entry.</p>
+ * Creates a new key entry.
*
* @param key The key.
* @param creationDate The entry creation date.
@@ -85,13 +83,11 @@ public final class PrivateKeyEntry extends PrimitiveEntry
super(TYPE, creationDate, properties);
if (key == null)
- {
- throw new IllegalArgumentException("no private key");
- }
- if (!(key instanceof PrivateKey) && !(key instanceof GnuSecretKey))
- {
- throw new IllegalArgumentException("not a private or secret key");
- }
+ throw new IllegalArgumentException("no private key");
+
+ if (! (key instanceof PrivateKey) && ! (key instanceof GnuSecretKey))
+ throw new IllegalArgumentException("not a private or secret key");
+
this.key = key;
}
@@ -109,9 +105,8 @@ public final class PrivateKeyEntry extends PrimitiveEntry
entry.defaultDecode(in);
String type = entry.properties.get("type");
if (type == null)
- {
- throw new MalformedKeyringException("no key type");
- }
+ throw new MalformedKeyringException("no key type");
+
if (type.equalsIgnoreCase("RAW-DSS"))
{
IKeyPairCodec coder = KeyPairCodecFactory.getInstance("dss");
@@ -128,42 +123,38 @@ public final class PrivateKeyEntry extends PrimitiveEntry
entry.key = coder.decodePrivateKey(entry.payload);
}
else if (type.equalsIgnoreCase("RAW"))
- {
- entry.key = new GnuSecretKey(entry.payload, null);
- }
+ entry.key = new GnuSecretKey(entry.payload, null);
else if (type.equalsIgnoreCase("PKCS8"))
{
try
{
KeyFactory kf = KeyFactory.getInstance("RSA");
- entry.key = kf.generatePrivate(new PKCS8EncodedKeySpec(
- entry.payload));
+ PKCS8EncodedKeySpec ks = new PKCS8EncodedKeySpec(entry.payload);
+ entry.key = kf.generatePrivate(ks);
}
- catch (Exception x)
+ catch (Exception ignored)
{
}
+
if (entry.key == null)
{
try
{
KeyFactory kf = KeyFactory.getInstance("DSA");
- entry.key = kf.generatePrivate(new PKCS8EncodedKeySpec(
- entry.payload));
+ PKCS8EncodedKeySpec ks = new PKCS8EncodedKeySpec(entry.payload);
+ entry.key = kf.generatePrivate(ks);
}
- catch (Exception x)
+ catch (Exception ignored)
{
}
+
if (entry.key == null)
- {
- throw new MalformedKeyringException(
- "could not decode PKCS#8 key");
- }
+ throw new MalformedKeyringException("could not decode PKCS#8 key");
}
}
else
- {
- throw new MalformedKeyringException("unsupported key type " + type);
- }
+ throw new MalformedKeyringException("unsupported key type " + type);
+
return entry;
}
@@ -171,7 +162,7 @@ public final class PrivateKeyEntry extends PrimitiveEntry
// -------------------------------------------------------------------------
/**
- * <p>Returns this entry's key.</p>
+ * Returns this entry's key.
*
* @return The key.
*/
@@ -212,8 +203,12 @@ public final class PrivateKeyEntry extends PrimitiveEntry
payload = key.getEncoded();
}
else
- {
- throw new IllegalArgumentException("unsupported private key");
- }
+ throw new IllegalArgumentException("unsupported private key");
+ }
+
+ public String toString()
+ {
+ return "PrivateKeyEntry{key="
+ + (key == null ? "-" : key.getClass().getName()) + "}";
}
}
diff --git a/gnu/javax/crypto/keyring/PublicKeyEntry.java b/gnu/javax/crypto/keyring/PublicKeyEntry.java
index 528e70cc6..bc09445fd 100644
--- a/gnu/javax/crypto/keyring/PublicKeyEntry.java
+++ b/gnu/javax/crypto/keyring/PublicKeyEntry.java
@@ -38,22 +38,19 @@ exception statement from your version. */
package gnu.javax.crypto.keyring;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-
-import java.security.PublicKey;
-import java.security.KeyFactory;
-import java.security.spec.X509EncodedKeySpec;
-
-import java.util.Date;
-
import gnu.java.security.key.IKeyPairCodec;
import gnu.java.security.key.KeyPairCodecFactory;
import gnu.java.security.key.dss.DSSPublicKey;
import gnu.java.security.key.rsa.GnuRSAPublicKey;
import gnu.javax.crypto.key.dh.GnuDHPublicKey;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.security.KeyFactory;
+import java.security.PublicKey;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Date;
+
public final class PublicKeyEntry extends PrimitiveEntry
{
diff --git a/gnu/javax/crypto/mac/OMAC.java b/gnu/javax/crypto/mac/OMAC.java
index c83320a1b..21156ac63 100644
--- a/gnu/javax/crypto/mac/OMAC.java
+++ b/gnu/javax/crypto/mac/OMAC.java
@@ -43,10 +43,8 @@ import gnu.java.security.util.Util;
import gnu.javax.crypto.cipher.CipherFactory;
import gnu.javax.crypto.cipher.IBlockCipher;
import gnu.javax.crypto.mode.IMode;
-import gnu.javax.crypto.mode.ModeFactory;
import java.security.InvalidKeyException;
-
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
diff --git a/gnu/javax/crypto/mode/BaseMode.java b/gnu/javax/crypto/mode/BaseMode.java
index 0a9ab2dab..f230cbd72 100644
--- a/gnu/javax/crypto/mode/BaseMode.java
+++ b/gnu/javax/crypto/mode/BaseMode.java
@@ -146,7 +146,7 @@ public abstract class BaseMode implements IMode
* of the method(s) available in the factory class.</p>
*
* @return the default value, in bytes, of the mode's block size.
- * @see gnu.crypto.mode.ModeFactory
+ * @see ModeFactory
*/
public int defaultBlockSize()
{
diff --git a/gnu/javax/crypto/mode/CTR.java b/gnu/javax/crypto/mode/CTR.java
index 49f4b9f3c..264d5399d 100644
--- a/gnu/javax/crypto/mode/CTR.java
+++ b/gnu/javax/crypto/mode/CTR.java
@@ -40,10 +40,8 @@ package gnu.javax.crypto.mode;
import gnu.java.security.Registry;
import gnu.java.security.util.Sequence;
-
import gnu.javax.crypto.cipher.IBlockCipher;
-import java.math.BigInteger;
import java.util.Arrays;
import java.util.Iterator;
diff --git a/gnu/javax/crypto/pad/IPad.java b/gnu/javax/crypto/pad/IPad.java
index 4b4c925e6..9cef4f78b 100644
--- a/gnu/javax/crypto/pad/IPad.java
+++ b/gnu/javax/crypto/pad/IPad.java
@@ -44,7 +44,7 @@ package gnu.javax.crypto.pad;
* <p>Padding algorithms serve to <i>pad</i> and <i>unpad</i> byte arrays usually
* as the last step in an <i>encryption</i> or respectively a <i>decryption</i>
* operation. Their input buffers are usually those processed by instances of
- * {@link gnu.crypto.mode.IMode} and/or {@link gnu.crypto.cipher.IBlockCipher}.</p>
+ * {@link gnu.javax.crypto.mode.IMode} and/or {@link gnu.javax.crypto.cipher.IBlockCipher}.</p>
*/
public interface IPad
{
diff --git a/gnu/javax/crypto/pad/PKCS1_V1_5.java b/gnu/javax/crypto/pad/PKCS1_V1_5.java
index 03c3d61a3..5f5a2cf47 100644
--- a/gnu/javax/crypto/pad/PKCS1_V1_5.java
+++ b/gnu/javax/crypto/pad/PKCS1_V1_5.java
@@ -92,7 +92,7 @@ public class PKCS1_V1_5 extends BasePad
* <p>Trivial package-private constructor for use by the <i>Factory</i> class.
* </p>
*
- * @see gnu.crypto.pad.PadFactory
+ * @see PadFactory
*/
PKCS1_V1_5()
{
diff --git a/gnu/javax/crypto/pad/PKCS7.java b/gnu/javax/crypto/pad/PKCS7.java
index 5697aff27..a5a1631a9 100644
--- a/gnu/javax/crypto/pad/PKCS7.java
+++ b/gnu/javax/crypto/pad/PKCS7.java
@@ -86,7 +86,7 @@ public final class PKCS7 extends BasePad
/**
* Trivial package-private constructor for use by the <i>Factory</i> class.<p>
*
- * @see gnu.crypto.pad.PadFactory
+ * @see PadFactory
*/
PKCS7()
{
diff --git a/gnu/javax/crypto/pad/TBC.java b/gnu/javax/crypto/pad/TBC.java
index 25c3e4286..c7e25cb23 100644
--- a/gnu/javax/crypto/pad/TBC.java
+++ b/gnu/javax/crypto/pad/TBC.java
@@ -85,7 +85,7 @@ public final class TBC extends BasePad
/**
* Trivial package-private constructor for use by the <i>Factory</i> class.<p>
*
- * @see gnu.crypto.pad.PadFactory
+ * @see PadFactory
*/
TBC()
{
diff --git a/gnu/javax/crypto/pad/TLS1.java b/gnu/javax/crypto/pad/TLS1.java
index 00a538f88..eb7e22d5d 100644
--- a/gnu/javax/crypto/pad/TLS1.java
+++ b/gnu/javax/crypto/pad/TLS1.java
@@ -38,8 +38,6 @@ exception statement from your version. */
package gnu.javax.crypto.pad;
-import gnu.java.security.util.Util;
-
/**
* The padding scheme used by the Transport Layer Security protocol,
* version 1. This padding scheme is used in the block-ciphered struct,
diff --git a/gnu/javax/crypto/prng/CSPRNG.java b/gnu/javax/crypto/prng/CSPRNG.java
index 6585dcb90..875ed9a0f 100644
--- a/gnu/javax/crypto/prng/CSPRNG.java
+++ b/gnu/javax/crypto/prng/CSPRNG.java
@@ -48,7 +48,6 @@ import gnu.java.security.prng.IRandom;
import gnu.java.security.prng.LimitReachedException;
import gnu.java.security.util.SimpleList;
import gnu.java.security.util.Util;
-
import gnu.javax.crypto.cipher.CipherFactory;
import gnu.javax.crypto.cipher.IBlockCipher;
@@ -56,15 +55,11 @@ import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.PrintStream;
-
import java.net.MalformedURLException;
import java.net.URL;
-
import java.security.AccessController;
import java.security.InvalidKeyException;
import java.security.PrivilegedAction;
-
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
@@ -114,7 +109,7 @@ public class CSPRNG extends BasePRNG
* <li>A {@link String}, indicating the path to the file.</li>
* </ol>
*
- * @see gnu.crypto.util.SimpleList
+ * @see gnu.java.security.util.SimpleList
*/
public static final String FILE_SOURCES = "gnu.crypto.prng.pool.files";
@@ -332,7 +327,7 @@ public class CSPRNG extends BasePRNG
* and its arguments.</p></dd>
*
* <dt>gnu.crypto.cspring.other</dt>
- * <dd><p>These properties are other sources, passed as the {@link OTHER_SOURCES}
+ * <dd><p>These properties are other sources, passed as the {@link #OTHER_SOURCES}
* parameter of the instance. The property value must be the full name
* of a class that implements the {@link EntropySource} interface and has a
* public no-argument constructor.</p></dd>
@@ -994,7 +989,7 @@ public class CSPRNG extends BasePRNG
// Field.
// -----------------------------------------------------------------------
- private byte counter;
+ protected byte counter;
// Constructor.
// -----------------------------------------------------------------------
diff --git a/gnu/javax/crypto/sasl/SaslUtil.java b/gnu/javax/crypto/sasl/SaslUtil.java
index e70312c0d..cb8d88e69 100644
--- a/gnu/javax/crypto/sasl/SaslUtil.java
+++ b/gnu/javax/crypto/sasl/SaslUtil.java
@@ -40,7 +40,6 @@ package gnu.javax.crypto.sasl;
import gnu.java.security.util.Util;
-import java.math.BigInteger;
import java.security.MessageDigest;
/**
diff --git a/gnu/javax/crypto/sasl/srp/PasswordFile.java b/gnu/javax/crypto/sasl/srp/PasswordFile.java
index 1628a4167..70a4bb65c 100644
--- a/gnu/javax/crypto/sasl/srp/PasswordFile.java
+++ b/gnu/javax/crypto/sasl/srp/PasswordFile.java
@@ -39,7 +39,6 @@ exception statement from your version. */
package gnu.javax.crypto.sasl.srp;
import gnu.java.security.Registry;
-import gnu.java.security.hash.IMessageDigest;
import gnu.java.security.util.Util;
import gnu.javax.crypto.key.srp6.SRPAlgorithm;
import gnu.javax.crypto.sasl.NoSuchUserException;
@@ -50,9 +49,9 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
+import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
-import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
diff --git a/gnu/javax/crypto/sasl/srp/SRPRegistry.java b/gnu/javax/crypto/sasl/srp/SRPRegistry.java
index 262cbcba3..9f7bba8e9 100644
--- a/gnu/javax/crypto/sasl/srp/SRPRegistry.java
+++ b/gnu/javax/crypto/sasl/srp/SRPRegistry.java
@@ -140,7 +140,7 @@ public interface SRPRegistry
/**
* Name of the SRP password database property --a reference to
- * {@link gnu.crypto.sasl.srp.PasswordFile} object.
+ * {@link PasswordFile} object.
*/
String PASSWORD_DB = "gnu.crypto.sasl.srp.password.db";
diff --git a/gnu/javax/imageio/jpeg/DCT.java b/gnu/javax/imageio/jpeg/DCT.java
index 2be4f5a4c..91b6eb88f 100644
--- a/gnu/javax/imageio/jpeg/DCT.java
+++ b/gnu/javax/imageio/jpeg/DCT.java
@@ -37,7 +37,6 @@ exception statement from your version. */
package gnu.javax.imageio.jpeg;
-// TODO: Clear copyright of this file.
/**
* Discrete Cosine Transformations.
*/
diff --git a/gnu/javax/imageio/jpeg/YCbCr_ColorSpace.java b/gnu/javax/imageio/jpeg/YCbCr_ColorSpace.java
index 9ac2ccaab..a3970b7fa 100644
--- a/gnu/javax/imageio/jpeg/YCbCr_ColorSpace.java
+++ b/gnu/javax/imageio/jpeg/YCbCr_ColorSpace.java
@@ -39,15 +39,6 @@ package gnu.javax.imageio.jpeg;
import java.awt.color.ColorSpace;
-/**
- * <p>Title: Symphony Image Object</p>
- * <p>Description: Creates and manages image formats</p>
- * <p>Copyright: Copyright (c) 2003</p>
- * <p>Company: Symphony</p>
- * @author not attributable
- * @version 1.0
- */
-
public class YCbCr_ColorSpace extends ColorSpace {
public YCbCr_ColorSpace() {
super(ColorSpace.TYPE_YCbCr, 3);
diff --git a/gnu/javax/imageio/jpeg/ZigZag.java b/gnu/javax/imageio/jpeg/ZigZag.java
index dcee7989c..0c19d74ff 100644
--- a/gnu/javax/imageio/jpeg/ZigZag.java
+++ b/gnu/javax/imageio/jpeg/ZigZag.java
@@ -37,7 +37,6 @@ exception statement from your version. */
package gnu.javax.imageio.jpeg;
-// TODO: Clear copyright of this file.
/**
* This class implements the Zig Zag Algorithm on any array with
* the same amount of rows and columns. It takes a matrix and in turn builds an
diff --git a/gnu/javax/print/CupsServer.java b/gnu/javax/print/CupsServer.java
index 6d9601fb9..0486e69de 100644
--- a/gnu/javax/print/CupsServer.java
+++ b/gnu/javax/print/CupsServer.java
@@ -84,24 +84,43 @@ public class CupsServer
/**
* Creates a <code>CupsServer</code> object which
- * tries to connect to the cups server on localhost.
+ * tries to connect to a cups server.
+ *
+ * If <code>gnu.javax.print.server</code> is explicitly set, then
+ * that hostname will be used. Otherwise it will default to localhost.
*
* @param username the username
* @param password the password for the username.
*/
public CupsServer(String username, String password)
{
+ this.username = username;
+ this.password = password;
+
+ this.uri = null;
+ try
+ {
+ String serv = System.getProperty("gnu.javax.print.server");
+ if( serv != null )
+ this.uri = new URI("http://"+serv+":631");
+ }
+ catch(URISyntaxException use)
+ {
+ throw new RuntimeException("gnu.javax.print.CupsServer value is not a valid hostname.");
+ }
+ catch(SecurityException se)
+ {
+ }
+
try
{
- this.uri = new URI("http://localhost:631");
+ if( this.uri == null )
+ this.uri = new URI("http://localhost:631");
}
catch (URISyntaxException e)
{
// does not happen
}
-
- this.username = username;
- this.password = password;
}
/**
@@ -193,7 +212,7 @@ public class CupsServer
Map printerAttributes = (Map) prAttr.get(i);
Set uris = (Set) printerAttributes.get(PrinterUriSupported.class);
PrinterUriSupported uri = (PrinterUriSupported) uris.toArray()[0];
-
+
try
{
CupsPrintService cups = new CupsPrintService(uri.getURI(),
diff --git a/gnu/javax/print/ipp/IppRequest.java b/gnu/javax/print/ipp/IppRequest.java
index 8abab5192..ccfa9b272 100644
--- a/gnu/javax/print/ipp/IppRequest.java
+++ b/gnu/javax/print/ipp/IppRequest.java
@@ -119,6 +119,11 @@ public class IppRequest
{
/**
+ * The printer-poll timeout.
+ */
+ private static final int timeout = 1000;
+
+ /**
* Helper class used to write the attributes of a request
* into the supplied data output stream in the correct way.
*
@@ -838,7 +843,12 @@ public class IppRequest
out.flush();
stream.flush();
-
+
+ // Set the connection timeout, for if the printer is offline.
+ // FIXME: The print services polling should probably be done in its
+ // own thread.
+ connection.setConnectTimeout( timeout );
+
int responseCode = responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK)
diff --git a/gnu/javax/swing/text/html/CharacterAttributeTranslator.java b/gnu/javax/swing/text/html/CharacterAttributeTranslator.java
new file mode 100644
index 000000000..9718189da
--- /dev/null
+++ b/gnu/javax/swing/text/html/CharacterAttributeTranslator.java
@@ -0,0 +1,156 @@
+/* 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 javax.swing.text.AbstractDocument;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.DefaultStyledDocument;
+import javax.swing.text.Element;
+import javax.swing.text.ElementIterator;
+import javax.swing.text.GapContent;
+import javax.swing.text.MutableAttributeSet;
+import javax.swing.text.SimpleAttributeSet;
+import javax.swing.text.StyleConstants;
+import javax.swing.text.html.HTML.Tag;
+
+/**
+ * This is a small utility class to translate HTML character attributes to
+ * Swing StyleConstants
+ */
+public class CharacterAttributeTranslator
+{
+ 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");
+ };
+
+ private static Color getColor(String s)
+ {
+ String s2 = (String)colorMap.get(s.toLowerCase());
+ if( s2 == null )
+ s2 = s;
+ try
+ {
+ return Color.decode(s2);
+ }
+ catch(NumberFormatException nfe)
+ {
+ return null;
+ }
+ }
+
+ public static boolean translateTag(MutableAttributeSet charAttr,
+ Tag t, MutableAttributeSet a)
+ {
+ if(t == Tag.FONT)
+ {
+ if(a.getAttribute("color") != null)
+ {
+ Color c = getColor(""+a.getAttribute("color"));
+ if( c == null )
+ return false;
+ charAttr.addAttribute(StyleConstants.Foreground, c);
+ return true;
+ }
+
+ if(a.getAttribute("size") != null)
+ {
+ // FIXME
+ // charAttr.addAttribute(StyleConstants.FontSize,
+ // new java.lang.Integer(72));
+ return true;
+ }
+ }
+
+ if( t == Tag.B )
+ {
+ charAttr.addAttribute(StyleConstants.Bold, new Boolean(true));
+ return true;
+ }
+
+ if( t == Tag.I )
+ {
+ charAttr.addAttribute(StyleConstants.Italic, new Boolean(true));
+ return true;
+ }
+
+ if( t == Tag.U )
+ {
+ charAttr.addAttribute(StyleConstants.Underline, new Boolean(true));
+ return true;
+ }
+
+ if( t == Tag.STRIKE )
+ {
+ charAttr.addAttribute(StyleConstants.StrikeThrough, new Boolean(true));
+ return true;
+ }
+
+ if( t == Tag.SUP )
+ {
+ charAttr.addAttribute(StyleConstants.Superscript, new Boolean(true));
+ return true;
+ }
+
+ if( t == Tag.SUB )
+ {
+ charAttr.addAttribute(StyleConstants.Subscript, new Boolean(true));
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/gnu/javax/swing/text/html/CombinedAttributes.java b/gnu/javax/swing/text/html/CombinedAttributes.java
new file mode 100644
index 000000000..b1e3de604
--- /dev/null
+++ b/gnu/javax/swing/text/html/CombinedAttributes.java
@@ -0,0 +1,213 @@
+/* CombinedAttributes.java -- A two combined sets of attributes
+ 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.io.Serializable;
+import java.util.Enumeration;
+
+import javax.swing.text.AttributeSet;
+import javax.swing.text.SimpleAttributeSet;
+
+/**
+ * Contains the two combined attribute sets what are searched subsequently.
+ * This is used to combine style sheet attributes with the HTML view attributes.
+ * The parent cannot be used as the view may have its own attribute hierarchy.
+ *
+ * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
+ */
+public class CombinedAttributes implements AttributeSet, Serializable
+{
+ /**
+ * Returns the elements from both enumerations.
+ */
+ class CombinedEnumeration implements Enumeration
+ {
+ /**
+ * Create a combined enumeration that enumerates over two enumerations.
+ *
+ * @param first the first enumeration to enumerate
+ * @param second the second enumeration to enumerate
+ */
+ CombinedEnumeration(Enumeration first, Enumeration second)
+ {
+ a = first;
+ b = second;
+ }
+
+ /**
+ * The first enumeration (elements returned first)
+ */
+ final Enumeration a;
+
+ /**
+ * The second enumeration (elements returned later)
+ */
+ final Enumeration b;
+
+ /** @inheritDoc */
+ public boolean hasMoreElements()
+ {
+ return a.hasMoreElements() || b.hasMoreElements();
+ }
+
+ /** @inheritDoc */
+ public Object nextElement()
+ {
+ return a.hasMoreElements() ? a.nextElement():b.nextElement();
+ }
+ }
+
+
+ /**
+ * The first attribute set.
+ */
+ final AttributeSet a;
+
+ /**
+ * The second attribute set.
+ */
+ final AttributeSet b;
+
+ /**
+ * Create the CombinedAttributes what search in the two sets. If any of the
+ * two passed sets is null, another set is returned. Otherwise, the combined
+ * attribute set is returned.
+ *
+ * @param primary the first set (searched first)
+ * @param secondary the second set (searched later).
+ */
+ public static AttributeSet combine(AttributeSet primary,
+ AttributeSet secondary)
+ {
+ if (primary == null)
+ return secondary;
+ else if (secondary == null)
+ return primary;
+ else
+ return new CombinedAttributes(primary, secondary);
+ }
+
+ /**
+ * Create the CombinedAttributes what search in the two sets.
+ *
+ * @param primary the first set (searched first)
+ * @param secondary the second set (searched later).
+ */
+ private CombinedAttributes(AttributeSet primary, AttributeSet secondary)
+ {
+ a = primary;
+ b = secondary;
+ }
+
+ /** @inheritDoc */
+ public boolean containsAttribute(Object name, Object value)
+ {
+ return a.containsAttribute(name, value) || b.containsAttribute(name, value);
+ }
+
+ /** @inheritDoc */
+ public boolean containsAttributes(AttributeSet attributes)
+ {
+ Enumeration names = attributes.getAttributeNames();
+ Object name;
+ while (names.hasMoreElements())
+ {
+ name = names.nextElement();
+ if (!containsAttribute(name, attributes.getAttribute(name)))
+ return false;
+ }
+ return true;
+ }
+
+ /** @inheritDoc */
+ public AttributeSet copyAttributes()
+ {
+ SimpleAttributeSet copy = new SimpleAttributeSet();
+ copy.addAttributes(a);
+ copy.addAttributes(b);
+ return copy;
+ }
+
+ /** @inheritDoc */
+ public Object getAttribute(Object key)
+ {
+ Object value = a.getAttribute(key);
+ if (value == null)
+ value = b.getAttribute(key);
+
+ return value;
+ }
+
+ /** @inheritDoc */
+ public int getAttributeCount()
+ {
+ return a.getAttributeCount()+b.getAttributeCount();
+ }
+
+ /** @inheritDoc */
+ public Enumeration getAttributeNames()
+ {
+ return new CombinedEnumeration(a.getAttributeNames(), b.getAttributeNames());
+ }
+
+ /**
+ * There is no one.
+ *
+ * @return null, always.
+ */
+ public AttributeSet getResolveParent()
+ {
+ return null;
+ }
+
+ /** @inheritDoc */
+ public boolean isDefined(Object attrName)
+ {
+ return a.isDefined(attrName) || b.isDefined(attrName);
+ }
+
+ /** @inheritDoc */
+ public boolean isEqual(AttributeSet attr)
+ {
+ if (attr.getAttributeCount() == getAttributeCount())
+ return containsAttributes(attr);
+ else
+ return false;
+ }
+}
diff --git a/gnu/javax/swing/text/html/ImageViewIconFactory.java b/gnu/javax/swing/text/html/ImageViewIconFactory.java
new file mode 100644
index 000000000..862e690c9
--- /dev/null
+++ b/gnu/javax/swing/text/html/ImageViewIconFactory.java
@@ -0,0 +1,282 @@
+package gnu.javax.swing.text.html;
+
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Graphics;
+import java.io.Serializable;
+
+import javax.swing.Icon;
+import javax.swing.plaf.metal.MetalLookAndFeel;
+
+/**
+ * Creates icons for ImageView. The icons reflect the basic ideas of the Sun's
+ * icons as they would be described in the text (sheet of paper with image and
+ * broken sheet of paper with image). They are not pixel to pixel identical and
+ * contain elements from the metal icon factory.
+ *
+ * @author Audrius Meskauskas (audriusa@bioinformatics.org)
+ */
+public class ImageViewIconFactory
+{
+ private static Icon noImageIcon;
+
+ private static Icon loadingImageIcon;
+
+ /**
+ * This icon reflects the general concept (broken sheet of paper with
+ * image), but is currently not pixel to pixel identical with the Sun's
+ * implementation.
+ */
+ public static class NoImageIcon implements Icon, Serializable
+ {
+ /**
+ * Creates a new icon.
+ */
+ public NoImageIcon()
+ {
+ // Nothing to do here.
+ }
+
+ /**
+ * Returns the width of the icon, in pixels.
+ *
+ * @return The width of the icon.
+ */
+ public int getIconWidth()
+ {
+ return 38;
+ }
+
+ /**
+ * Returns the height of the icon, in pixels.
+ *
+ * @return The height of the icon.
+ */
+ public int getIconHeight()
+ {
+ return 38;
+ }
+
+ /**
+ * Paints the icon using colors from the {@link MetalLookAndFeel}.
+ *
+ * @param c
+ * the component (ignored).
+ * @param g
+ * the graphics device.
+ * @param x
+ * the x-coordinate for the top-left of the icon.
+ * @param y
+ * the y-coordinate for the top-left of the icon.
+ */
+ public void paintIcon(Component c, Graphics g, int x, int y)
+ {
+ // frame
+ Color savedColor = g.getColor();
+
+ g.setColor(MetalLookAndFeel.getBlack());
+
+ g.drawLine(x, y, x + 19, y);
+
+ g.drawLine(x, y + 1, x, y + 5);
+ g.drawLine(x, y + 13, x, y + 25);
+
+ g.drawLine(x, y + 25, x + 22, y + 25);
+
+ g.drawLine(x + 22, y + 25, x + 22, y + 21);
+ g.drawLine(x + 22, y + 13, x + 22, y + 6);
+
+ g.drawLine(x + 22, y + 6, x + 19, y);
+
+ g.drawLine(x + 17, y + 2, x + 21, y + 6);
+
+ g.drawLine(x + 18, y + 1, x + 19, y + 1);
+
+ g.setColor(MetalLookAndFeel.getControlShadow());
+
+ g.drawLine(x + 1, y + 1, x + 17, y + 1);
+
+ g.drawLine(x + 1, y + 1, x + 1, y + 5);
+ g.drawLine(x + 1, y + 13, x + 1, y + 24);
+
+ g.drawLine(x + 1, y + 24, x + 21, y + 24);
+
+ g.drawLine(x + 21, y + 24, x + 21, y + 21);
+ g.drawLine(x + 21, y + 13, x + 21, y + 7);
+
+ g.drawLine(x + 18, y + 2, x + 20, y + 4);
+
+ // Breaking line
+
+ // Shadow
+ g.drawLine(x + 1, y + 6, x + 20, y + 13);
+ g.drawLine(x + 1, y + 13, x + 20, y + 20);
+
+ // Edge
+ g.setColor(MetalLookAndFeel.getBlack());
+ g.drawLine(x, y + 6, x + 21, y + 14);
+ g.drawLine(x, y + 12, x + 21, y + 20);
+
+ // Picture
+
+ y += 1;
+ x += 3;
+
+ g.setColor(MetalLookAndFeel.getBlack());
+
+ // roof
+ g.drawLine(x + 4, y + 5, x + 8, y + 1);
+ g.drawLine(x + 8, y + 1, x + 15, y + 8);
+
+ // chimney
+ g.drawLine(x + 11, y + 2, x + 11, y + 4);
+ g.drawLine(x + 12, y + 2, x + 12, y + 5);
+
+ g.setColor(MetalLookAndFeel.getControlDarkShadow());
+
+ // roof paint
+ int xx = x + 8;
+ for (int i = 0; i < 4; i++)
+ g.drawLine(xx - i, y + 2 + i, xx + i, y + 2 + i);
+ g.fillRect(x + 4, y + 6, 9, 2);
+
+ // base of house
+ g.drawLine(x + 3, y + 14, x + 3, y + 18);
+ g.drawLine(x + 3, y + 18, x + 13, y + 18);
+
+ g.setColor(savedColor);
+ }
+ }
+
+ /**
+ * This icon reflects the general concept (sheet of paper with image), but is
+ * currently not pixel to pixel identical with the Sun's implementation.
+ */
+ public static class LoadingImageIcon implements Icon, Serializable
+ {
+
+ /**
+ * Creates a new icon.
+ */
+ public LoadingImageIcon()
+ {
+ // Nothing to do here.
+ }
+
+ /**
+ * Returns the width of the icon, in pixels.
+ *
+ * @return The width of the icon.
+ */
+ public int getIconWidth()
+ {
+ return 38;
+ }
+
+ /**
+ * Returns the height of the icon, in pixels.
+ *
+ * @return The height of the icon.
+ */
+ public int getIconHeight()
+ {
+ return 38;
+ }
+
+ /**
+ * Paints the icon using colors from the {@link MetalLookAndFeel}.
+ *
+ * @param c
+ * the component (ignored).
+ * @param g
+ * the graphics device.
+ * @param x
+ * the x-coordinate for the top-left of the icon.
+ * @param y
+ * the y-coordinate for the top-left of the icon.
+ */
+ public void paintIcon(Component c, Graphics g, int x, int y)
+ {
+ // frame
+ Color savedColor = g.getColor();
+
+ g.setColor(Color.black);
+ g.drawLine(x, y, x + 19, y);
+ g.drawLine(x, y + 1, x, y + 25);
+ g.drawLine(x, y + 25, x + 22, y + 25);
+ g.drawLine(x + 22, y + 25, x + 22, y + 6);
+ g.drawLine(x + 22, y + 6, x + 19, y);
+
+ g.drawLine(x + 17, y + 2, x + 21, y + 6);
+ g.drawLine(x + 18, y + 1, x + 19, y + 1);
+
+ g.setColor(new Color(204, 204, 255));
+
+ g.drawLine(x + 1, y + 1, x + 17, y + 1);
+ g.drawLine(x + 1, y + 1, x + 1, y + 24);
+ g.drawLine(x + 1, y + 24, x + 21, y + 24);
+ g.drawLine(x + 21, y + 24, x + 21, y + 7);
+ g.drawLine(x + 18, y + 2, x + 20, y + 4);
+
+ // Picture (house)
+
+ y += 3;
+ x += 3;
+
+ g.setColor(MetalLookAndFeel.getBlack());
+
+ // roof
+ g.drawLine(x + 1, y + 8, x + 8, y + 1);
+ g.drawLine(x + 8, y + 1, x + 15, y + 8);
+
+ // base of house
+ g.drawLine(x + 3, y + 6, x + 3, y + 15);
+ g.drawLine(x + 3, y + 15, x + 13, y + 15);
+ g.drawLine(x + 13, y + 6, x + 13, y + 15);
+
+ // door frame
+ g.drawLine(x + 6, y + 9, x + 6, y + 15);
+ g.drawLine(x + 6, y + 9, x + 10, y + 9);
+ g.drawLine(x + 10, y + 9, x + 10, y + 15);
+
+ // chimney
+ g.drawLine(x + 11, y + 2, x + 11, y + 4);
+ g.drawLine(x + 12, y + 2, x + 12, y + 5);
+
+ g.setColor(MetalLookAndFeel.getControlDarkShadow());
+
+ // roof paint
+ int xx = x + 8;
+ for (int i = 0; i < 4; i++)
+ g.drawLine(xx - i, y + 2 + i, xx + i, y + 2 + i);
+ g.fillRect(x + 4, y + 6, 9, 2);
+
+ // door knob
+ g.drawLine(x + 9, y + 12, x + 9, y + 12);
+
+ // house paint
+ g.setColor(MetalLookAndFeel.getPrimaryControl());
+ g.drawLine(x + 4, y + 8, x + 12, y + 8);
+ g.fillRect(x + 4, y + 9, 2, 6);
+ g.fillRect(x + 11, y + 9, 2, 6);
+
+ g.setColor(savedColor);
+ }
+ }
+
+ public static Icon getNoImageIcon()
+ {
+ if (noImageIcon == null)
+ noImageIcon = new NoImageIcon();
+ return noImageIcon;
+ }
+
+ public static Icon getLoadingImageIcon()
+ {
+ if (loadingImageIcon == null)
+ loadingImageIcon = new LoadingImageIcon();
+ return loadingImageIcon;
+ }
+
+}
diff --git a/gnu/xml/dom/DomNode.java b/gnu/xml/dom/DomNode.java
index c06a4c1f1..f0915eb5e 100644
--- a/gnu/xml/dom/DomNode.java
+++ b/gnu/xml/dom/DomNode.java
@@ -1113,12 +1113,15 @@ public abstract class DomNode
{
DomDocument doc = (nodeType == DOCUMENT_NODE) ?
(DomDocument) node : node.owner;
+ boolean building = doc.building;
+ doc.building = true; // Permit certain structural rules
for (DomNode ctx = first; ctx != null; ctx = ctx.next)
{
DomNode newChild = (DomNode) ctx.cloneNode(deep);
newChild.setOwner(doc);
node.appendChild(newChild);
}
+ doc.building = building;
}
if (nodeType == ENTITY_REFERENCE_NODE)
{
diff --git a/include/Makefile.am b/include/Makefile.am
index 5cda78e88..b01611aa4 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -37,9 +37,11 @@ $(top_srcdir)/include/gnu_xml_libxmlj_transform_GnomeTransformer.h \
$(top_srcdir)/include/gnu_xml_libxmlj_transform_GnomeTransformerFactory.h
GTKPEER_H_FILES = \
+$(top_srcdir)/include/gnu_java_awt_peer_gtk_CairoSurface.h \
+$(top_srcdir)/include/gnu_java_awt_peer_gtk_CairoGraphics2D.h \
+$(top_srcdir)/include/gnu_java_awt_peer_gtk_ComponentGraphics.h \
+$(top_srcdir)/include/gnu_java_awt_peer_gtk_ComponentGraphicsCopy.h \
$(top_srcdir)/include/gnu_java_awt_peer_gtk_GdkFontPeer.h \
-$(top_srcdir)/include/gnu_java_awt_peer_gtk_GdkGraphics.h \
-$(top_srcdir)/include/gnu_java_awt_peer_gtk_GdkGraphics2D.h \
$(top_srcdir)/include/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.h \
$(top_srcdir)/include/gnu_java_awt_peer_gtk_GdkPixbufDecoder.h \
$(top_srcdir)/include/gnu_java_awt_peer_gtk_GdkRobotPeer.h \
@@ -72,6 +74,7 @@ $(top_srcdir)/include/gnu_java_awt_peer_gtk_GtkTextAreaPeer.h \
$(top_srcdir)/include/gnu_java_awt_peer_gtk_GtkTextFieldPeer.h \
$(top_srcdir)/include/gnu_java_awt_peer_gtk_GtkToolkit.h \
$(top_srcdir)/include/gnu_java_awt_peer_gtk_GtkWindowPeer.h \
+$(top_srcdir)/include/gnu_java_awt_peer_gtk_GtkVolatileImage.h \
$(top_srcdir)/include/gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.h
QTPEER_H_FILES = \
@@ -120,6 +123,7 @@ $(QTPEER_H_FILES) \
$(top_srcdir)/include/gnu_java_net_VMPlainDatagramSocketImpl.h \
$(top_srcdir)/include/gnu_java_net_VMPlainSocketImpl.h \
$(top_srcdir)/include/gnu_java_net_local_LocalSocketImpl.h \
+$(top_srcdir)/include/gnu_java_nio_VMChannel.h \
$(top_srcdir)/include/gnu_java_nio_VMPipe.h \
$(top_srcdir)/include/gnu_java_nio_VMSelector.h \
$(top_srcdir)/include/gnu_java_nio_channels_FileChannelImpl.h \
@@ -136,6 +140,7 @@ $(top_srcdir)/include/java_lang_VMSystem.h \
$(top_srcdir)/include/java_lang_reflect_VMArray.h \
$(top_srcdir)/include/java_net_VMInetAddress.h \
$(top_srcdir)/include/java_net_VMNetworkInterface.h \
+$(top_srcdir)/include/java_net_VMURLConnection.h \
$(top_srcdir)/include/java_nio_VMDirectByteBuffer.h \
$(top_srcdir)/include/java_nio_MappedByteBufferImpl.h \
$(top_srcdir)/include/java_util_VMTimeZone.h
@@ -171,6 +176,8 @@ $(top_srcdir)/include/gnu_java_net_VMPlainSocketImpl.h: $(top_srcdir)/vm/referen
$(JAVAH) -o $@ gnu.java.net.VMPlainSocketImpl
$(top_srcdir)/include/gnu_java_net_local_LocalSocketImpl.h: $(top_srcdir)/gnu/java/net/local/LocalSocketImpl.java
$(JAVAH) -o $@ gnu.java.net.local.LocalSocketImpl
+$(top_srcdir)/include/gnu_java_nio_VMChannel.h: $(top_srcdir)/vm/reference/gnu/java/nio/VMChannel.java
+ $(JAVAH) -o $@ gnu.java.nio.VMChannel
$(top_srcdir)/include/gnu_java_nio_VMPipe.h: $(top_srcdir)/vm/reference/gnu/java/nio/VMPipe.java
$(JAVAH) -o $@ gnu.java.nio.VMPipe
$(top_srcdir)/include/gnu_java_nio_VMSelector.h: $(top_srcdir)/vm/reference/gnu/java/nio/VMSelector.java
@@ -197,6 +204,8 @@ $(top_srcdir)/include/java_net_VMInetAddress.h: $(top_srcdir)/vm/reference/java/
$(JAVAH) -o $@ java.net.VMInetAddress
$(top_srcdir)/include/java_net_VMNetworkInterface.h: $(top_srcdir)/vm/reference/java/net/VMNetworkInterface.java
$(JAVAH) -o $@ java.net.VMNetworkInterface
+$(top_srcdir)/include/java_net_VMURLConnection.h: $(top_srcdir)/vm/reference/java/net/VMURLConnection.java
+ $(JAVAH) -o $@ java.net.VMURLConnection
$(top_srcdir)/include/java_nio_VMDirectByteBuffer.h: $(top_srcdir)/vm/reference/java/nio/VMDirectByteBuffer.java
$(JAVAH) -o $@ java.nio.VMDirectByteBuffer
$(top_srcdir)/include/java_nio_MappedByteBufferImpl.h: $(top_srcdir)/java/nio/MappedByteBufferImpl.java
diff --git a/include/gnu_java_awt_peer_gtk_CairoGraphics2D.h b/include/gnu_java_awt_peer_gtk_CairoGraphics2D.h
new file mode 100644
index 000000000..0895f86c1
--- /dev/null
+++ b/include/gnu_java_awt_peer_gtk_CairoGraphics2D.h
@@ -0,0 +1,45 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+
+#ifndef __gnu_java_awt_peer_gtk_CairoGraphics2D__
+#define __gnu_java_awt_peer_gtk_CairoGraphics2D__
+
+#include <jni.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+JNIEXPORT jlong JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_init (JNIEnv *env, jobject, jlong);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_disposeNative (JNIEnv *env, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_drawPixels (JNIEnv *env, jobject, jintArray, jint, jint, jint, jdoubleArray);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_setGradient (JNIEnv *env, jobject, jdouble, jdouble, jdouble, jdouble, jint, jint, jint, jint, jint, jint, jint, jint, jboolean);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_setTexturePixels (JNIEnv *env, jobject, jintArray, jint, jint, jint);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSetMatrix (JNIEnv *env, jobject, jdoubleArray);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSetOperator (JNIEnv *env, jobject, jint);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSetRGBAColor (JNIEnv *env, jobject, jdouble, jdouble, jdouble, jdouble);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSetFillRule (JNIEnv *env, jobject, jint);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSetLine (JNIEnv *env, jobject, jdouble, jint, jint, jdouble);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSetDash (JNIEnv *env, jobject, jdoubleArray, jint, jdouble);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoDrawGlyphVector (JNIEnv *env, jobject, jobject, jfloat, jfloat, jint, jintArray, jfloatArray);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoRelCurveTo (JNIEnv *env, jobject, jdouble, jdouble, jdouble, jdouble, jdouble, jdouble);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoRectangle (JNIEnv *env, jobject, jdouble, jdouble, jdouble, jdouble);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoNewPath (JNIEnv *env, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoClosePath (JNIEnv *env, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoMoveTo (JNIEnv *env, jobject, jdouble, jdouble);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoRelMoveTo (JNIEnv *env, jobject, jdouble, jdouble);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoLineTo (JNIEnv *env, jobject, jdouble, jdouble);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoRelLineTo (JNIEnv *env, jobject, jdouble, jdouble);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoCurveTo (JNIEnv *env, jobject, jdouble, jdouble, jdouble, jdouble, jdouble, jdouble);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoStroke (JNIEnv *env, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoFill (JNIEnv *env, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoClip (JNIEnv *env, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoResetClip (JNIEnv *env, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoPreserveClip (JNIEnv *env, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSurfaceSetFilter (JNIEnv *env, jobject, jint);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gnu_java_awt_peer_gtk_CairoGraphics2D__ */
diff --git a/include/gnu_java_awt_peer_gtk_CairoSurface.h b/include/gnu_java_awt_peer_gtk_CairoSurface.h
new file mode 100644
index 000000000..e8c13d705
--- /dev/null
+++ b/include/gnu_java_awt_peer_gtk_CairoSurface.h
@@ -0,0 +1,28 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+
+#ifndef __gnu_java_awt_peer_gtk_CairoSurface__
+#define __gnu_java_awt_peer_gtk_CairoSurface__
+
+#include <jni.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_create (JNIEnv *env, jobject, jint, jint, jint);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_destroy (JNIEnv *env, jobject);
+JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_nativeGetElem (JNIEnv *env, jobject, jint);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_nativeSetElem (JNIEnv *env, jobject, jint, jint);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_drawSurface (JNIEnv *env, jobject, jobject, jdoubleArray);
+JNIEXPORT jintArray JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_getPixels (JNIEnv *env, jobject, jint);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_setPixels (JNIEnv *env, jobject, jintArray);
+JNIEXPORT jlong JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_newCairoContext (JNIEnv *env, jobject);
+JNIEXPORT jlong JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_getFlippedBuffer (JNIEnv *env, jobject, jint);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_CairoSurface_copyAreaNative (JNIEnv *env, jobject, jint, jint, jint, jint, jint, jint, jint);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gnu_java_awt_peer_gtk_CairoSurface__ */
diff --git a/include/gnu_java_awt_peer_gtk_ComponentGraphics.h b/include/gnu_java_awt_peer_gtk_ComponentGraphics.h
new file mode 100644
index 000000000..03917502b
--- /dev/null
+++ b/include/gnu_java_awt_peer_gtk_ComponentGraphics.h
@@ -0,0 +1,24 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+
+#ifndef __gnu_java_awt_peer_gtk_ComponentGraphics__
+#define __gnu_java_awt_peer_gtk_ComponentGraphics__
+
+#include <jni.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+JNIEXPORT jlong JNICALL Java_gnu_java_awt_peer_gtk_ComponentGraphics_initState (JNIEnv *env, jobject, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_ComponentGraphics_start_1gdk_1drawing (JNIEnv *env, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_ComponentGraphics_end_1gdk_1drawing (JNIEnv *env, jobject);
+JNIEXPORT jboolean JNICALL Java_gnu_java_awt_peer_gtk_ComponentGraphics_hasXRender (JNIEnv *env, jclass);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_ComponentGraphics_copyAreaNative (JNIEnv *env, jobject, jobject, jint, jint, jint, jint, jint, jint);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_ComponentGraphics_drawVolatile (JNIEnv *env, jobject, jobject, jobject, jint, jint, jint, jint);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gnu_java_awt_peer_gtk_ComponentGraphics__ */
diff --git a/include/gnu_java_awt_peer_gtk_ComponentGraphicsCopy.h b/include/gnu_java_awt_peer_gtk_ComponentGraphicsCopy.h
new file mode 100644
index 000000000..8e4b2cdb3
--- /dev/null
+++ b/include/gnu_java_awt_peer_gtk_ComponentGraphicsCopy.h
@@ -0,0 +1,20 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+
+#ifndef __gnu_java_awt_peer_gtk_ComponentGraphicsCopy__
+#define __gnu_java_awt_peer_gtk_ComponentGraphicsCopy__
+
+#include <jni.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_ComponentGraphicsCopy_getPixbuf (JNIEnv *env, jobject, jobject, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_ComponentGraphicsCopy_copyPixbuf (JNIEnv *env, jobject, jobject, jobject, jint, jint, jint, jint);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gnu_java_awt_peer_gtk_ComponentGraphicsCopy__ */
diff --git a/include/gnu_java_awt_peer_gtk_GdkFontPeer.h b/include/gnu_java_awt_peer_gtk_GdkFontPeer.h
index 900146674..1ef60d40a 100644
--- a/include/gnu_java_awt_peer_gtk_GdkFontPeer.h
+++ b/include/gnu_java_awt_peer_gtk_GdkFontPeer.h
@@ -13,9 +13,11 @@ extern "C"
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkFontPeer_initStaticState (JNIEnv *env, jclass);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkFontPeer_initState (JNIEnv *env, jobject);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkFontPeer_dispose (JNIEnv *env, jobject);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkFontPeer_setFont (JNIEnv *env, jobject, jstring, jint, jint, jboolean);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkFontPeer_setFont (JNIEnv *env, jobject, jstring, jint, jint);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkFontPeer_getFontMetrics (JNIEnv *env, jobject, jdoubleArray);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkFontPeer_getTextMetrics (JNIEnv *env, jobject, jstring, jdoubleArray);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkFontPeer_releasePeerGraphicsResource (JNIEnv *env, jobject);
+JNIEXPORT jbyteArray JNICALL Java_gnu_java_awt_peer_gtk_GdkFontPeer_getTrueTypeTable (JNIEnv *env, jobject, jbyte, jbyte, jbyte, jbyte);
JNIEXPORT jobject JNICALL Java_gnu_java_awt_peer_gtk_GdkFontPeer_getGlyphVector (JNIEnv *env, jobject, jstring, jobject, jobject);
#ifdef __cplusplus
diff --git a/include/gnu_java_awt_peer_gtk_GdkGraphics.h b/include/gnu_java_awt_peer_gtk_GdkGraphics.h
deleted file mode 100644
index 8a87738f2..000000000
--- a/include/gnu_java_awt_peer_gtk_GdkGraphics.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-
-#ifndef __gnu_java_awt_peer_gtk_GdkGraphics__
-#define __gnu_java_awt_peer_gtk_GdkGraphics__
-
-#include <jni.h>
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_initStaticState (JNIEnv *env, jclass);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_initState__Lgnu_java_awt_peer_gtk_GtkComponentPeer_2 (JNIEnv *env, jobject, jobject);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_initStateUnlocked (JNIEnv *env, jobject, jobject);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_initState__II (JNIEnv *env, jobject, jint, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_initFromImage (JNIEnv *env, jobject, jobject);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_nativeCopyState (JNIEnv *env, jobject, jobject);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_connectSignals (JNIEnv *env, jobject, jobject);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_clearRect (JNIEnv *env, jobject, jint, jint, jint, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_copyArea (JNIEnv *env, jobject, jint, jint, jint, jint, jint, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_nativeDispose (JNIEnv *env, jobject);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_drawLine (JNIEnv *env, jobject, jint, jint, jint, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_drawArc (JNIEnv *env, jobject, jint, jint, jint, jint, jint, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_fillArc (JNIEnv *env, jobject, jint, jint, jint, jint, jint, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_drawOval (JNIEnv *env, jobject, jint, jint, jint, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_fillOval (JNIEnv *env, jobject, jint, jint, jint, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_drawPolygon (JNIEnv *env, jobject, jintArray, jintArray, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_fillPolygon (JNIEnv *env, jobject, jintArray, jintArray, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_drawPolyline (JNIEnv *env, jobject, jintArray, jintArray, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_drawRect (JNIEnv *env, jobject, jint, jint, jint, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_fillRect (JNIEnv *env, jobject, jint, jint, jint, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_drawString (JNIEnv *env, jobject, jobject, jstring, jint, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_setClipRectangle (JNIEnv *env, jobject, jint, jint, jint, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_setFGColor (JNIEnv *env, jobject, jint, jint, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_setFunction (JNIEnv *env, jobject, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_translateNative (JNIEnv *env, jobject, jint, jint);
-#undef gnu_java_awt_peer_gtk_GdkGraphics_GDK_COPY
-#define gnu_java_awt_peer_gtk_GdkGraphics_GDK_COPY 0L
-#undef gnu_java_awt_peer_gtk_GdkGraphics_GDK_XOR
-#define gnu_java_awt_peer_gtk_GdkGraphics_GDK_XOR 2L
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __gnu_java_awt_peer_gtk_GdkGraphics__ */
diff --git a/include/gnu_java_awt_peer_gtk_GdkGraphics2D.h b/include/gnu_java_awt_peer_gtk_GdkGraphics2D.h
deleted file mode 100644
index 2d29cfc73..000000000
--- a/include/gnu_java_awt_peer_gtk_GdkGraphics2D.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-
-#ifndef __gnu_java_awt_peer_gtk_GdkGraphics2D__
-#define __gnu_java_awt_peer_gtk_GdkGraphics2D__
-
-#include <jni.h>
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initStaticState (JNIEnv *env, jclass);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initStateUnlocked (JNIEnv *env, jobject, jobject);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState__Lgnu_java_awt_peer_gtk_GtkComponentPeer_2 (JNIEnv *env, jobject, jobject);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState__II (JNIEnv *env, jobject, jint, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState___3III (JNIEnv *env, jobject, jintArray, jint, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_copyState (JNIEnv *env, jobject, jobject);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_dispose (JNIEnv *env, jobject);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSurfaceSetFilter (JNIEnv *env, jobject, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSurfaceSetFilterUnlocked (JNIEnv *env, jobject, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_connectSignals (JNIEnv *env, jobject, jobject);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_gdkDrawDrawable (JNIEnv *env, jobject, jobject, jint, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_drawPixels (JNIEnv *env, jobject, jintArray, jint, jint, jint, jdoubleArray);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setTexturePixelsUnlocked (JNIEnv *env, jobject, jintArray, jint, jint, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setTexturePixels (JNIEnv *env, jobject, jintArray, jint, jint, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setGradient (JNIEnv *env, jobject, jdouble, jdouble, jdouble, jdouble, jint, jint, jint, jint, jint, jint, jint, jint, jboolean);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setGradientUnlocked (JNIEnv *env, jobject, jdouble, jdouble, jdouble, jdouble, jint, jint, jint, jint, jint, jint, jint, jint, jboolean);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSave (JNIEnv *env, jobject);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRestore (JNIEnv *env, jobject);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMatrix (JNIEnv *env, jobject, jdoubleArray);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMatrixUnlocked (JNIEnv *env, jobject, jdoubleArray);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetOperator (JNIEnv *env, jobject, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetRGBAColor (JNIEnv *env, jobject, jdouble, jdouble, jdouble, jdouble);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetRGBAColorUnlocked (JNIEnv *env, jobject, jdouble, jdouble, jdouble, jdouble);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetFillRule (JNIEnv *env, jobject, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineWidth (JNIEnv *env, jobject, jdouble);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineWidthUnlocked (JNIEnv *env, jobject, jdouble);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineCap (JNIEnv *env, jobject, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineCapUnlocked (JNIEnv *env, jobject, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineJoin (JNIEnv *env, jobject, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineJoinUnlocked (JNIEnv *env, jobject, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetDash (JNIEnv *env, jobject, jdoubleArray, jint, jdouble);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetDashUnlocked (JNIEnv *env, jobject, jdoubleArray, jint, jdouble);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMiterLimit (JNIEnv *env, jobject, jdouble);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMiterLimitUnlocked (JNIEnv *env, jobject, jdouble);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoNewPath (JNIEnv *env, jobject);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoMoveTo (JNIEnv *env, jobject, jdouble, jdouble);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoLineTo (JNIEnv *env, jobject, jdouble, jdouble);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoCurveTo (JNIEnv *env, jobject, jdouble, jdouble, jdouble, jdouble, jdouble, jdouble);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelMoveTo (JNIEnv *env, jobject, jdouble, jdouble);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelLineTo (JNIEnv *env, jobject, jdouble, jdouble);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelCurveTo (JNIEnv *env, jobject, jdouble, jdouble, jdouble, jdouble, jdouble, jdouble);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRectangle (JNIEnv *env, jobject, jdouble, jdouble, jdouble, jdouble);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoClosePath (JNIEnv *env, jobject);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoStroke (JNIEnv *env, jobject);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoFill (JNIEnv *env, jobject);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoClip (JNIEnv *env, jobject);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoDrawGlyphVector (JNIEnv *env, jobject, jobject, jfloat, jfloat, jint, jintArray, jfloatArray);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoDrawGdkTextLayout (JNIEnv *env, jobject, jobject, jfloat, jfloat);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_releasePeerGraphicsResource (JNIEnv *env, jclass, jobject);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __gnu_java_awt_peer_gtk_GdkGraphics2D__ */
diff --git a/include/gnu_java_awt_peer_gtk_GdkTextLayout.h b/include/gnu_java_awt_peer_gtk_GdkTextLayout.h
index c74a574e7..680c4165f 100644
--- a/include/gnu_java_awt_peer_gtk_GdkTextLayout.h
+++ b/include/gnu_java_awt_peer_gtk_GdkTextLayout.h
@@ -11,10 +11,12 @@ extern "C"
#endif
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkTextLayout_setText (JNIEnv *env, jobject, jstring);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkTextLayout_setFont (JNIEnv *env, jobject, jobject);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkTextLayout_getExtents (JNIEnv *env, jobject, jdoubleArray, jdoubleArray);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkTextLayout_indexToPos (JNIEnv *env, jobject, jint, jdoubleArray);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkTextLayout_initState (JNIEnv *env, jobject);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkTextLayout_dispose (JNIEnv *env, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkTextLayout_cairoDrawGdkTextLayout (JNIEnv *env, jobject, jobject, jfloat, jfloat);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkTextLayout_initStaticState (JNIEnv *env, jclass);
JNIEXPORT jobject JNICALL Java_gnu_java_awt_peer_gtk_GdkTextLayout_getOutline (JNIEnv *env, jobject, jobject);
diff --git a/include/gnu_java_awt_peer_gtk_GtkCanvasPeer.h b/include/gnu_java_awt_peer_gtk_GtkCanvasPeer.h
index 44ab6870c..e774713a7 100644
--- a/include/gnu_java_awt_peer_gtk_GtkCanvasPeer.h
+++ b/include/gnu_java_awt_peer_gtk_GtkCanvasPeer.h
@@ -11,7 +11,6 @@ extern "C"
#endif
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkCanvasPeer_create (JNIEnv *env, jobject);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkCanvasPeer_realize (JNIEnv *env, jobject);
#ifdef __cplusplus
}
diff --git a/include/gnu_java_awt_peer_gtk_GtkComponentPeer.h b/include/gnu_java_awt_peer_gtk_GtkComponentPeer.h
index 207e08d05..f2014595f 100644
--- a/include/gnu_java_awt_peer_gtk_GtkComponentPeer.h
+++ b/include/gnu_java_awt_peer_gtk_GtkComponentPeer.h
@@ -26,7 +26,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetS
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetParent (JNIEnv *env, jobject, jobject);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetRequestFocus (JNIEnv *env, jobject);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetDispatchKeyEvent (JNIEnv *env, jobject, jint, jlong, jint, jint, jint);
-JNIEXPORT jboolean JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_isRealized (JNIEnv *env, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_realize (JNIEnv *env, jobject);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_setNativeEventMask (JNIEnv *env, jobject);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_connectSignals (JNIEnv *env, jobject);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_setNativeBounds (JNIEnv *env, jobject, jint, jint, jint, jint);
diff --git a/include/gnu_java_awt_peer_gtk_GtkImage.h b/include/gnu_java_awt_peer_gtk_GtkImage.h
index 48940a1ca..0ea798bc2 100644
--- a/include/gnu_java_awt_peer_gtk_GtkImage.h
+++ b/include/gnu_java_awt_peer_gtk_GtkImage.h
@@ -10,15 +10,14 @@ extern "C"
{
#endif
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkImage_initFromBuffer (JNIEnv *env, jobject, jlong);
JNIEXPORT jintArray JNICALL Java_gnu_java_awt_peer_gtk_GtkImage_getPixels (JNIEnv *env, jobject);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkImage_setPixels (JNIEnv *env, jobject, jintArray);
JNIEXPORT jboolean JNICALL Java_gnu_java_awt_peer_gtk_GtkImage_loadPixbuf (JNIEnv *env, jobject, jstring);
JNIEXPORT jboolean JNICALL Java_gnu_java_awt_peer_gtk_GtkImage_loadImageFromData (JNIEnv *env, jobject, jbyteArray);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkImage_createPixmap (JNIEnv *env, jobject);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkImage_freePixmap (JNIEnv *env, jobject);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkImage_createScaledPixmap (JNIEnv *env, jobject, jobject, jint);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkImage_drawPixelsScaled (JNIEnv *env, jobject, jobject, jint, jint, jint, jint, jint, jint, jint, jboolean);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkImage_drawPixelsScaledFlipped (JNIEnv *env, jobject, jobject, jint, jint, jint, jboolean, jboolean, jint, jint, jint, jint, jint, jint, jint, jint, jboolean);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkImage_createPixbuf (JNIEnv *env, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkImage_freePixbuf (JNIEnv *env, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkImage_createScaledPixbuf (JNIEnv *env, jobject, jobject, jint);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkImage_createFromPixbuf (JNIEnv *env, jobject);
#ifdef __cplusplus
diff --git a/include/gnu_java_awt_peer_gtk_GtkVolatileImage.h b/include/gnu_java_awt_peer_gtk_GtkVolatileImage.h
new file mode 100644
index 000000000..67c08cf7d
--- /dev/null
+++ b/include/gnu_java_awt_peer_gtk_GtkVolatileImage.h
@@ -0,0 +1,22 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+
+#ifndef __gnu_java_awt_peer_gtk_GtkVolatileImage__
+#define __gnu_java_awt_peer_gtk_GtkVolatileImage__
+
+#include <jni.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+JNIEXPORT jlong JNICALL Java_gnu_java_awt_peer_gtk_GtkVolatileImage_init (JNIEnv *env, jobject, jobject, jint, jint);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkVolatileImage_destroy (JNIEnv *env, jobject);
+JNIEXPORT jintArray JNICALL Java_gnu_java_awt_peer_gtk_GtkVolatileImage_getPixels (JNIEnv *env, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkVolatileImage_update (JNIEnv *env, jobject, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gnu_java_awt_peer_gtk_GtkVolatileImage__ */
diff --git a/include/gnu_java_nio_VMChannel.h b/include/gnu_java_nio_VMChannel.h
new file mode 100644
index 000000000..28f9048d2
--- /dev/null
+++ b/include/gnu_java_nio_VMChannel.h
@@ -0,0 +1,24 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+
+#ifndef __gnu_java_nio_VMChannel__
+#define __gnu_java_nio_VMChannel__
+
+#include <jni.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+JNIEXPORT void JNICALL Java_gnu_java_nio_VMChannel_setBlocking (JNIEnv *env, jobject, jint, jboolean);
+JNIEXPORT jint JNICALL Java_gnu_java_nio_VMChannel_read (JNIEnv *env, jobject, jint, jobject);
+JNIEXPORT jlong JNICALL Java_gnu_java_nio_VMChannel_readScattering (JNIEnv *env, jobject, jint, jobjectArray, jint, jint);
+JNIEXPORT jint JNICALL Java_gnu_java_nio_VMChannel_write (JNIEnv *env, jobject, jint, jobject);
+JNIEXPORT jlong JNICALL Java_gnu_java_nio_VMChannel_writeGathering (JNIEnv *env, jobject, jint, jobjectArray, jint, jint);
+JNIEXPORT void JNICALL Java_gnu_java_nio_VMChannel_initIDs (JNIEnv *env, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gnu_java_nio_VMChannel__ */
diff --git a/include/java_net_VMURLConnection.h b/include/java_net_VMURLConnection.h
new file mode 100644
index 000000000..270a14a75
--- /dev/null
+++ b/include/java_net_VMURLConnection.h
@@ -0,0 +1,22 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+
+#ifndef __java_net_VMURLConnection__
+#define __java_net_VMURLConnection__
+
+#include <jni.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+JNIEXPORT void JNICALL Java_java_net_VMURLConnection_init (JNIEnv *env, jclass);
+JNIEXPORT jstring JNICALL Java_java_net_VMURLConnection_guessContentTypeFromBuffer (JNIEnv *env, jclass, jbyteArray, jint);
+#undef java_net_VMURLConnection_LENGTH
+#define java_net_VMURLConnection_LENGTH 1024L
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __java_net_VMURLConnection__ */
diff --git a/java/awt/BasicStroke.java b/java/awt/BasicStroke.java
index bf111d080..3e259216f 100644
--- a/java/awt/BasicStroke.java
+++ b/java/awt/BasicStroke.java
@@ -363,7 +363,7 @@ public class BasicStroke implements Stroke
* Compares this <code>BasicStroke</code> for equality with an arbitrary
* object. This method returns <code>true</code> if and only if:
* <ul>
- * <li><code>o</code> is an instanceof <code>BasicStroke</code>;<li>
+ * <li><code>o</code> is an instanceof <code>BasicStroke</code>;</li>
* <li>this object has the same width, line cap style, line join style,
* miter limit, dash array and dash phase as <code>o</code>.</li>
* </ul>
diff --git a/java/awt/ColorPaintContext.java b/java/awt/ColorPaintContext.java
index fc7376b80..2996f899f 100644
--- a/java/awt/ColorPaintContext.java
+++ b/java/awt/ColorPaintContext.java
@@ -117,7 +117,7 @@ class ColorPaintContext implements PaintContext
{
cachedRaster = new ColorRaster(colorModel, 0, 0, width, height, color);
}
- return cachedRaster.createChild(0 ,0 ,width ,height ,x ,y , null);
+ return cachedRaster.createChild(0 ,0 ,width ,height ,0 ,0 , null);
}
/**
diff --git a/java/awt/Component.java b/java/awt/Component.java
index dbbec8ac1..cc42d04f2 100644
--- a/java/awt/Component.java
+++ b/java/awt/Component.java
@@ -2067,11 +2067,9 @@ public abstract class Component
*/
public VolatileImage createVolatileImage(int width, int height)
{
- if (GraphicsEnvironment.isHeadless())
- return null;
- GraphicsConfiguration config = getGraphicsConfiguration();
- return config == null ? null
- : config.createCompatibleVolatileImage(width, height);
+ if (peer != null)
+ return peer.createVolatileImage(width, height);
+ return null;
}
/**
@@ -2090,11 +2088,9 @@ public abstract class Component
ImageCapabilities caps)
throws AWTException
{
- if (GraphicsEnvironment.isHeadless())
- return null;
- GraphicsConfiguration config = getGraphicsConfiguration();
- return config == null ? null
- : config.createCompatibleVolatileImage(width, height, caps);
+ if (peer != null)
+ return peer.createVolatileImage(width, height);
+ return null;
}
/**
@@ -4810,8 +4806,38 @@ p * <li>the set of backward traversal keys
{
Object target = e.getSource ();
Event translated = null;
+
+ if (e instanceof WindowEvent)
+ {
+ WindowEvent we = (WindowEvent) e;
+ int id = we.id;
+ int newId = 0;
+
+ switch (id)
+ {
+ case WindowEvent.WINDOW_DEICONIFIED:
+ newId = Event.WINDOW_DEICONIFY;
+ break;
+ case WindowEvent.WINDOW_CLOSED:
+ case WindowEvent.WINDOW_CLOSING:
+ newId = Event.WINDOW_DESTROY;
+ break;
+ case WindowEvent.WINDOW_ICONIFIED:
+ newId = Event.WINDOW_ICONIFY;
+ break;
+ case WindowEvent.WINDOW_GAINED_FOCUS:
+ newId = Event.GOT_FOCUS;
+ break;
+ case WindowEvent.WINDOW_LOST_FOCUS:
+ newId = Event.LOST_FOCUS;
+ break;
+ default:
+ return null;
+ }
- if (e instanceof InputEvent)
+ translated = new Event(target, 0, newId, 0, 0, 0, 0);
+ }
+ else if (e instanceof InputEvent)
{
InputEvent ie = (InputEvent) e;
long when = ie.getWhen ();
@@ -5052,7 +5078,12 @@ p * <li>the set of backward traversal keys
.dispatchEvent(e))
return;
case MouseEvent.MOUSE_PRESSED:
- if (isLightweight() && !e.isConsumed())
+ // A mouse click on an enabled lightweight component
+ // which has not yet been marked as consumed by any
+ // other mouse listener results in a focus traversal
+ // to that component.
+ if (isLightweight()
+ && isEnabled() && !e.isConsumed())
requestFocus();
break;
}
diff --git a/java/awt/Container.java b/java/awt/Container.java
index 2419a7bd2..85a68ce13 100644
--- a/java/awt/Container.java
+++ b/java/awt/Container.java
@@ -457,8 +457,44 @@ public class Container extends Component
{
synchronized (getTreeLock ())
{
- while (ncomponents > 0)
- remove(0);
+ // In order to allow the same bad tricks to be used as in RI
+ // this code has to stay exactly that way: In a real-life app
+ // a Container subclass implemented its own vector for
+ // subcomponents, supplied additional addXYZ() methods
+ // and overrode remove(int) and removeAll (the latter calling
+ // super.removeAll() ).
+ // By doing it this way, user code cannot prevent the correct
+ // removal of components.
+ for ( int index = 0; index < ncomponents; index++)
+ {
+ Component r = component[index];
+
+ ComponentListener[] list = r.getComponentListeners();
+ for (int j = 0; j < list.length; j++)
+ r.removeComponentListener(list[j]);
+
+ r.removeNotify();
+
+ if (layoutMgr != null)
+ layoutMgr.removeLayoutComponent(r);
+
+ r.parent = null;
+
+ if (isShowing ())
+ {
+ // Post event to notify of removing the component.
+ ContainerEvent ce
+ = new ContainerEvent(this,
+ ContainerEvent.COMPONENT_REMOVED,
+ r);
+
+ getToolkit().getSystemEventQueue().postEvent(ce);
+ }
+ }
+
+ invalidate();
+
+ ncomponents = 0;
}
}
diff --git a/java/awt/ContainerOrderFocusTraversalPolicy.java b/java/awt/ContainerOrderFocusTraversalPolicy.java
index 152482c88..23b4ac2e8 100644
--- a/java/awt/ContainerOrderFocusTraversalPolicy.java
+++ b/java/awt/ContainerOrderFocusTraversalPolicy.java
@@ -111,14 +111,16 @@ public class ContainerOrderFocusTraversalPolicy extends FocusTraversalPolicy
ancestor = current.getFocusCycleRootAncestor ();
if (ancestor == prevAncestor)
{
- // We've reached the top focus cycle root ancestor. Check
- // if it is root.
- if (ancestor != root)
+ // We've reached the top focus cycle root ancestor. Check
+ // if it is root.
+ if (ancestor == null)
+ ancestor = root;
+ else if (ancestor != root)
throw new IllegalArgumentException ("the given container is not"
+ " a focus cycle root of the"
+ " current component");
- else
- break;
+ else
+ break;
}
prevAncestor = ancestor;
}
@@ -136,7 +138,6 @@ public class ContainerOrderFocusTraversalPolicy extends FocusTraversalPolicy
return getFirstComponent ((Container) current);
Container parent = current.getParent ();
-
synchronized (parent.getTreeLock ())
{
Component[] components = parent.getComponents ();
@@ -146,47 +147,104 @@ public class ContainerOrderFocusTraversalPolicy extends FocusTraversalPolicy
// Find component's index.
for (int i = 0; i < numComponents; i++)
{
- if (components[i] == current)
+ if (components[i].equals(current))
componentIndex = i;
}
- // Search forward for the next acceptable component.
- for (int i = componentIndex + 1; i < numComponents; i++)
- {
- if (accept (components[i]))
- return components[i];
+ // Search forward for the next acceptable component.
+ // Search through all components at least one time
+ // i.e. start at componentIndex + 1 --> nComponents -1 --> 0 ---> componentIndex
+ int i = componentIndex + 1;
+ int end = numComponents - 1;
+ Component next = getNextAvailableComponent(components, i, end);
+ if (next != null)
+ return next;
+
+ // Now check remainder of components from 0 to componentIndex
+ i = 0;
+ end = componentIndex;
+ next = getNextAvailableComponent(components, i, end);
+ if (next != null)
+ return next;
+
+ // No focusable components after current in its Container. So go
+ // to the next Component after current's Container (parent).
+ Component result = getComponentAfter (root, parent);
+ return result;
+ }
+ }
+
+ /**
+ * Gets the next available component in the array between the given range.
+ *
+ * @param components - the array of components.
+ * @param start - where to start
+ * @param end - where to end
+ * @return next component if found
+ */
+ private Component getNextAvailableComponent(Component[] components, int start, int end)
+ {
+ while (start <= end)
+ {
+ Component c = components[start];
+
+ if (c.visible && c.isDisplayable() && c.enabled && c.focusable)
+ return c;
- if (components[i] instanceof Container)
- {
- Component result = getFirstComponent ((Container) components[i]);
+ if (c instanceof Container)
+ {
+ Component result = getFirstComponent((Container) c);
- if (result != null
- && implicitDownCycleTraversal)
- return result;
- }
+ if (result != null && implicitDownCycleTraversal && result.visible
+ && result.isDisplayable() && result.enabled && result.focusable)
+ return result;
}
+ start++;
+ }
- // No focusable components after current in its Container. So go
- // to the next Component after current's Container (parent).
- Component result = getComponentAfter (root, parent);
+ return null;
+ }
- return result;
+ /**
+ * Gets the previous available component in the array between the given range.
+ *
+ * @param components - the array of components.
+ * @param start - where to start
+ * @param end - where to end
+ * @return previous component if found
+ */
+ Component getPrevAvailableComponent(Component[] components, int start, int end)
+ {
+ while (start >= end)
+ {
+ Component c = components[start];
+ if (c.visible && c.isDisplayable() && c.enabled && c.focusable)
+ return c;
+
+ if (c instanceof Container)
+ {
+ Component result = getLastComponent((Container) c);
+
+ if (result != null
+ && (result.visible && result.isDisplayable() && result.enabled && result.focusable))
+ return result;
+ }
+ start--;
}
+ return null;
}
/**
* Returns the Component that should receive the focus before
- * <code>current</code>. <code>root</code> must be a focus cycle
- * root of current.
- *
+ * <code>current</code>. <code>root</code> must be a focus cycle root of
+ * current.
+ *
* @param root a focus cycle root of current
* @param current a (possibly indirect) child of root, or root itself
- *
- * @return the previous Component in the focus traversal order for
- * root, or null if no acceptable Component exists.
- *
- * @exception IllegalArgumentException If root is not a focus cycle
- * root of current, or if either root or current is null.
+ * @return the previous Component in the focus traversal order for root, or
+ * null if no acceptable Component exists.
+ * @exception IllegalArgumentException If root is not a focus cycle root of
+ * current, or if either root or current is null.
*/
public Component getComponentBefore (Container root, Component current)
{
@@ -207,7 +265,9 @@ public class ContainerOrderFocusTraversalPolicy extends FocusTraversalPolicy
{
// We've reached the top focus cycle root ancestor. Check
// if it is root.
- if (ancestor != root)
+ if (ancestor == null)
+ ancestor = root;
+ else if (ancestor != root)
throw new IllegalArgumentException ("the given container is not"
+ " a focus cycle root of the"
+ " current component");
@@ -244,20 +304,20 @@ public class ContainerOrderFocusTraversalPolicy extends FocusTraversalPolicy
componentIndex = i;
}
- // Search backward for the next acceptable component.
- for (int i = componentIndex - 1; i >= 0; i--)
- {
- if (accept (components[i]))
- return components[i];
-
- if (components[i] instanceof Container)
- {
- Component result = getLastComponent ((Container) components[i]);
-
- if (result != null)
- return result;
- }
- }
+ // Search through all components at least one time
+ // i.e. start at componentIndex - 1 --> 0 --> numComponents -1 ---> componentIndex
+ int i = componentIndex - 1;
+ int end = 0;
+ Component prev = getPrevAvailableComponent(components, i, end);
+ if (prev != null)
+ return prev;
+
+ // Now check remainder of components
+ i = numComponents -1;
+ end = componentIndex;
+ prev = getPrevAvailableComponent(components, i, end);
+ if (prev != null)
+ return prev;
// No focusable components before current in its Container. So go
// to the previous Component before current's Container (parent).
@@ -286,7 +346,8 @@ public class ContainerOrderFocusTraversalPolicy extends FocusTraversalPolicy
|| !root.isDisplayable ())
return null;
- if (accept (root))
+ if (root.visible && root.isDisplayable() && root.enabled
+ && root.focusable)
return root;
Component[] componentArray = root.getComponents ();
@@ -295,14 +356,16 @@ public class ContainerOrderFocusTraversalPolicy extends FocusTraversalPolicy
{
Component component = componentArray [i];
- if (accept (component))
+ if (component.visible && component.isDisplayable() && component.enabled
+ && component.focusable)
return component;
if (component instanceof Container)
{
Component result = getFirstComponent ((Container) component);
- if (result != null)
+ if (result != null
+ && (result.visible && result.isDisplayable() && result.enabled && result.focusable))
return result;
}
}
@@ -329,7 +392,8 @@ public class ContainerOrderFocusTraversalPolicy extends FocusTraversalPolicy
|| !root.isDisplayable ())
return null;
- if (accept (root))
+ if (root.visible && root.isDisplayable() && root.enabled
+ && root.focusable)
return root;
Component[] componentArray = root.getComponents ();
@@ -338,14 +402,17 @@ public class ContainerOrderFocusTraversalPolicy extends FocusTraversalPolicy
{
Component component = componentArray [i];
- if (accept (component))
+ if (component.visible && component.isDisplayable() && component.enabled
+ && component.focusable)
return component;
if (component instanceof Container)
{
Component result = getLastComponent ((Container) component);
- if (result != null)
+ if (result != null &&
+ result.visible && result.isDisplayable() && result.enabled
+ && result.focusable)
return result;
}
}
diff --git a/java/awt/DefaultKeyboardFocusManager.java b/java/awt/DefaultKeyboardFocusManager.java
index a60cefd9c..037cb834c 100644
--- a/java/awt/DefaultKeyboardFocusManager.java
+++ b/java/awt/DefaultKeyboardFocusManager.java
@@ -274,10 +274,12 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager
public boolean dispatchKeyEvent (KeyEvent e)
{
- Component focusOwner = getGlobalPermanentFocusOwner ();
-
+ Component focusOwner = getFocusOwner();
+ if (focusOwner == null)
+ focusOwner = getFocusedWindow();
+
if (focusOwner != null)
- redispatchEvent(focusOwner, e);
+ redispatchEvent(focusOwner, e);
// Loop through all registered KeyEventPostProcessors, giving
// each a chance to process this event.
@@ -294,7 +296,7 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager
// MenuShortcut.
if (postProcessKeyEvent (e))
return true;
-
+
// Always return true.
return true;
}
diff --git a/java/awt/EventDispatchThread.java b/java/awt/EventDispatchThread.java
index a64cdae85..7cb8af831 100644
--- a/java/awt/EventDispatchThread.java
+++ b/java/awt/EventDispatchThread.java
@@ -43,6 +43,11 @@ package java.awt;
*/
class EventDispatchThread extends Thread
{
+ /**
+ * The default priority when no property has been set.
+ */
+ private static final int DEFAULT_PRIORITY = NORM_PRIORITY + 1;
+
private static int dispatchThreadNum;
private EventQueue queue;
@@ -52,7 +57,22 @@ class EventDispatchThread extends Thread
super();
setName("AWT-EventQueue-" + ++dispatchThreadNum);
this.queue = queue;
- setPriority(NORM_PRIORITY + 1);
+
+ int priority = DEFAULT_PRIORITY;
+ try
+ {
+ String priorityString =
+ System.getProperty("gnu.awt.dispatchthread.priority");
+ if (priorityString != null)
+ {
+ priority = Integer.parseInt(priorityString);
+ }
+ }
+ catch (NumberFormatException ex)
+ {
+ // Ignore and use default.
+ }
+ setPriority(priority);
}
public void run()
diff --git a/java/awt/Font.java b/java/awt/Font.java
index 2e4c9f61c..a52f63408 100644
--- a/java/awt/Font.java
+++ b/java/awt/Font.java
@@ -1013,7 +1013,7 @@ public class Font implements Serializable
*/
public int getNumGlyphs()
{
- return peer.getMissingGlyphCode(this);
+ return peer.getNumGlyphs(this);
}
/**
diff --git a/java/awt/Graphics2D.java b/java/awt/Graphics2D.java
index 3faa9dc0c..b3ecbc58a 100644
--- a/java/awt/Graphics2D.java
+++ b/java/awt/Graphics2D.java
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2002, 2004 Free Software Foundation
+/* Copyright (C) 2000, 2002, 2004, 2006, Free Software Foundation
This file is part of GNU Classpath.
@@ -45,10 +45,35 @@ import java.awt.image.BufferedImageOp;
import java.awt.image.ImageObserver;
import java.awt.image.RenderedImage;
import java.awt.image.renderable.RenderableImage;
+import java.awt.print.PageFormat;
+import java.awt.print.Printable;
import java.text.AttributedCharacterIterator;
import java.util.Map;
/**
+ * An abstract class defining a device independent two-dimensional vector
+ * graphics API. Concrete subclasses implement this API for output of
+ * vector graphics to: (*)
+ * <p>
+ * <ul>
+ * <li>a {@link javax.swing.JComponent} - in the
+ * {@link javax.swing.JComponent#paint(Graphics)} method, the incoming
+ * {@link Graphics} should always be an instance of
+ * <code>Graphics2D</code> (*);</li>
+ * <li>a {@link BufferedImage} - see
+ * {@link BufferedImage#createGraphics()} (*);</li>
+ * <li>a {@link java.awt.print.PrinterJob} - in the
+ * {@link Printable#print(Graphics, PageFormat, int)} method, the incoming
+ * {@link Graphics} should always be an instance of <code>Graphics2D</code>
+ * (*).</li>
+ * </ul>
+ * <p>
+ * (*) Support for this API is not fully implemented in GNU Classpath yet.
+ * <p>
+ * Third party libraries provide support for output to other formats via this
+ * API, including encapsulated postscript (EPS), portable document format (PDF),
+ * and scalable vector graphics (SVG).
+ *
* @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
*/
public abstract class Graphics2D extends Graphics
@@ -70,6 +95,14 @@ public abstract class Graphics2D extends Graphics
super.fill3DRect(x, y, width, height, raised);
}
+ /**
+ * Draws an outline around a shape using the current stroke and paint.
+ *
+ * @param shape the shape (<code>null</code> not permitted).
+ *
+ * @see #getStroke()
+ * @see #getPaint()
+ */
public abstract void draw(Shape shape);
public abstract boolean drawImage(Image image, AffineTransform xform,
@@ -86,18 +119,57 @@ public abstract class Graphics2D extends Graphics
public abstract void drawRenderableImage(RenderableImage image,
AffineTransform xform);
+ /**
+ * Draws a string at the specified location, using the current font.
+ *
+ * @param text the string to draw.
+ * @param x the x-coordinate.
+ * @param y the y-coordinate.
+ *
+ * @see Graphics#setFont(Font)
+ */
public abstract void drawString(String text, int x, int y);
+ /**
+ * Draws a string at the specified location, using the current font.
+ *
+ * @param text the string to draw.
+ * @param x the x-coordinate.
+ * @param y the y-coordinate.
+ *
+ * @see Graphics#setFont(Font)
+ */
public abstract void drawString(String text, float x, float y);
+ /**
+ * Draws an attributed string at the specified location.
+ *
+ * @param iterator the source of the attributed text.
+ * @param x the x-coordinate.
+ * @param y the y-coordinate.
+ */
public abstract void drawString(AttributedCharacterIterator iterator,
int x, int y);
+ /**
+ * Draws an attributed string at the specified location.
+ *
+ * @param iterator the source of the attributed text.
+ * @param x the x-coordinate.
+ * @param y the y-coordinate.
+ */
public abstract void drawString(AttributedCharacterIterator iterator,
float x, float y);
- // public abstract void drawGlyphVector(GlyphVector g, float x, float y);
-
+ /**
+ * Fills the interior of the specified <code>shape</code> using the current
+ * paint.
+ *
+ * @param shape the shape to fill (<code>null</code> not permitted).
+ *
+ * @see #draw(Shape)
+ * @see #getPaint()
+ */
public abstract void fill(Shape shape);
public abstract boolean hit(Rectangle rect, Shape text,
@@ -105,21 +177,72 @@ public abstract class Graphics2D extends Graphics
public abstract GraphicsConfiguration getDeviceConfiguration();
+ /**
+ * Sets the current compositing rule.
+ *
+ * @param comp the composite.
+ *
+ * @see #getComposite()
+ */
public abstract void setComposite(Composite comp);
-
+
+ /**
+ * Sets the paint to be used for subsequent drawing operations.
+ *
+ * @param paint the paint (<code>null</code> not permitted).
+ *
+ * @see #getPaint()
+ */
public abstract void setPaint(Paint paint);
+ /**
+ * Sets the stroke to be used for subsequent drawing operations.
+ *
+ * @param stroke the stroke (<code>null</code> not permitted).
+ *
+ * @see #getStroke()
+ */
public abstract void setStroke(Stroke stroke);
+ /**
+ * Adds or updates a hint in the current rendering hints table.
+ *
+ * @param hintKey the hint key.
+ * @param hintValue the hint value.
+ */
public abstract void setRenderingHint(RenderingHints.Key hintKey,
Object hintValue);
+ /**
+ * Returns the current value of a rendering hint.
+ *
+ * @param hintKey the key for the hint.
+ *
+ * @return The value for the specified hint.
+ */
public abstract Object getRenderingHint(RenderingHints.Key hintKey);
+ /**
+ * Replaces the current rendering hints with the supplied hints.
+ *
+ * @param hints the hints.
+ *
+ * @see #addRenderingHints(Map)
+ */
public abstract void setRenderingHints(Map hints);
+ /**
+ * Adds/updates the rendering hint.
+ *
+ * @param hints the hints to add or update.
+ */
public abstract void addRenderingHints(Map hints);
+ /**
+ * Returns the current rendering hints.
+ *
+ * @return The current rendering hints.
+ */
public abstract RenderingHints getRenderingHints();
public abstract void translate(int x, int y);
@@ -134,25 +257,104 @@ public abstract class Graphics2D extends Graphics
public abstract void shear(double shearX, double shearY);
- public abstract void transform(AffineTransform Tx);
+ /**
+ * Sets the current transform to a concatenation of <code>transform</code>
+ * and the existing transform.
+ *
+ * @param transform the transform.
+ */
+ public abstract void transform(AffineTransform transform);
- public abstract void setTransform(AffineTransform Tx);
-
+ /**
+ * Sets the current transform. If the caller specifies a <code>null</code>
+ * transform, this method should set the current transform to the
+ * identity transform.
+ *
+ * @param transform the transform (<code>null</code> permitted).
+ *
+ * @see #getTransform()
+ */
+ public abstract void setTransform(AffineTransform transform);
+
+ /**
+ * Returns the current transform.
+ *
+ * @return The current transform.
+ *
+ * @see #setTransform(AffineTransform)
+ */
public abstract AffineTransform getTransform();
+ /**
+ * Returns the current paint.
+ *
+ * @return The current paint.
+ *
+ * @see #setPaint(Paint)
+ */
public abstract Paint getPaint();
+ /**
+ * Returns the current compositing rule.
+ *
+ * @return The current compositing rule.
+ *
+ * @see #setComposite(Composite)
+ */
public abstract Composite getComposite();
+ /**
+ * Sets the background color (used by the
+ * {@link Graphics#clearRect(int, int, int, int)} method).
+ *
+ * @param color the color.
+ *
+ * @see #getBackground()
+ */
public abstract void setBackground(Color color);
+ /**
+ * Returns the color used by the
+ * {@link Graphics#clearRect(int, int, int, int)} method.
+ *
+ * @return The background color.
+ *
+ * @see #setBackground(Color)
+ */
public abstract Color getBackground();
+ /**
+ * Returns the current stroke.
+ *
+ * @return The current stroke.
+ *
+ * @see #setStroke(Stroke)
+ */
public abstract Stroke getStroke();
+ /**
+ * Sets the clip region to the intersection of the current clipping region
+ * and <code>s</code>.
+ *
+ * @param s the shape to intersect with the current clipping region.
+ *
+ * @see Graphics#setClip(Shape)
+ */
public abstract void clip(Shape s);
- public abstract FontRenderContext getFontRenderContext ();
-
- public abstract void drawGlyphVector (GlyphVector g, float x, float y);
+ /**
+ * Returns the font render context.
+ *
+ * @return The font render context.
+ */
+ public abstract FontRenderContext getFontRenderContext();
+
+ /**
+ * Draws a glyph vector at the specified location.
+ *
+ * @param g the glyph vector.
+ * @param x the x-coordinate.
+ * @param y the y-coordinate.
+ */
+ public abstract void drawGlyphVector(GlyphVector g, float x, float y);
}
diff --git a/java/awt/GraphicsConfiguration.java b/java/awt/GraphicsConfiguration.java
index f68a1e6ba..792b2cc1b 100644
--- a/java/awt/GraphicsConfiguration.java
+++ b/java/awt/GraphicsConfiguration.java
@@ -65,6 +65,13 @@ import java.awt.image.VolatileImage;
*/
public abstract class GraphicsConfiguration
{
+
+ /** The cached image capabilities. */
+ private ImageCapabilities imageCapabilities;
+
+ /** The cached buffer capabilities. */
+ private BufferCapabilities bufferCapabilities;
+
/**
* The default constructor.
*
@@ -218,9 +225,14 @@ public abstract class GraphicsConfiguration
* @since 1.4
*/
public BufferCapabilities getBufferCapabilities()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ if (imageCapabilities == null)
+ getImageCapabilities();
+
+ if (bufferCapabilities == null)
+ bufferCapabilities = new BufferCapabilities(imageCapabilities,
+ imageCapabilities, null);
+ return bufferCapabilities;
}
/**
@@ -230,8 +242,9 @@ public abstract class GraphicsConfiguration
* @since 1.4
*/
public ImageCapabilities getImageCapabilities()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ if (imageCapabilities == null)
+ imageCapabilities = new ImageCapabilities(false);
+ return imageCapabilities;
}
} // class GraphicsConfiguration
diff --git a/java/awt/LightweightDispatcher.java b/java/awt/LightweightDispatcher.java
index 860646402..3be18910b 100644
--- a/java/awt/LightweightDispatcher.java
+++ b/java/awt/LightweightDispatcher.java
@@ -67,6 +67,13 @@ class LightweightDispatcher
* as well as the MOUSE_RELEASED event following the dragging.
*/
private Component dragTarget;
+
+ /**
+ * Stores the button number which started the drag operation. This is needed
+ * because we want to handle only one drag operation and only the button that
+ * started the dragging should be able to stop it (by a button release).
+ */
+ private int dragButton;
/**
* The last mouse event target. If the target changes, additional
@@ -121,15 +128,41 @@ class LightweightDispatcher
/**
* Handles all mouse events that are targetted at toplevel containers
* (Window instances) and dispatches them to the correct lightweight child.
- *
+ *
* @param ev the mouse event
* @return whether or not we found a lightweight that handled the event.
*/
private boolean handleMouseEvent(MouseEvent ev)
{
Window window = (Window) ev.getSource();
- Component target = window.findComponentAt(ev.getX(), ev.getY());
- target = findTarget(target);
+ // Find the target for the mouse event. We first seach the deepest
+ // component at the specified location. The we go up to its parent and
+ // try to find a neighbor of the deepest component that is suitable as
+ // mouse event target (it must be showing, at that location and have either
+ // a MouseListener or MouseMotionListener installed). If no such component
+ // is found, then we walk up the container hierarchy and find the next
+ // container that has a MouseListener or MouseMotionListener installed.
+ Component deepest = window.findComponentAt(ev.getX(), ev.getY());
+ if (deepest == null)
+ return false;
+ Container parent = deepest.getParent();
+ Point loc = ev.getPoint();
+ loc = AWTUtilities.convertPoint(window, loc.x, loc.y, parent);
+ Component target = null;
+ if (parent != null)
+ {
+ target = findTarget(deepest.getParent(), loc);
+ while (target == null && parent != null)
+ {
+ if (parent.getMouseListeners().length > 0
+ || parent.getMouseMotionListeners().length > 0)
+ {
+ target = parent;
+ }
+ else
+ parent = parent.getParent();
+ }
+ }
if (target == null || target.isLightweight())
{
// Dispatch additional MOUSE_EXITED and MOUSE_ENTERED if event target
@@ -146,7 +179,16 @@ class LightweightDispatcher
ev.getClickCount(), ev.isPopupTrigger());
lastTarget.dispatchEvent(mouseExited);
}
- if (target != null)
+
+ // If a target exists dispatch the MOUSE_ENTERED event only if
+ // there is currently no component from which a drag operation
+ // started (dragTarget == null) or the target is that component
+ // (dragTarget == target)
+ // That way a user can click and hold on a button (putting it into
+ // the armed state), move the cursor above other buttons without
+ // affecting their rollover state and get back to the initial
+ // button.
+ if (target != null && (dragTarget == null || dragTarget == target))
{
Point p = AWTUtilities.convertPoint(window, ev.getX(), ev.getY(),
target);
@@ -161,12 +203,30 @@ class LightweightDispatcher
switch (ev.getID())
{
case MouseEvent.MOUSE_PRESSED:
- dragTarget = target;
+ // Handle the start of a drag operation or discard the event if
+ // one is already in progress. This prevents focus changes with the
+ // other mouse buttons when one is used for dragging.
+ if (dragTarget == null)
+ {
+ lastTarget = dragTarget = target;
+
+ // Save the button that started the drag operation.
+ dragButton = ev.getButton();
+ }
+ else
+ return false;
+
break;
case MouseEvent.MOUSE_RELEASED:
- if (dragTarget != null)
- target = dragTarget;
- dragTarget = null;
+ // Stop the drag operation only when the button that started
+ // it was released.
+ if (dragTarget != null && dragButton == ev.getButton())
+ {
+ target = dragTarget;
+ dragTarget = null;
+ }
+
+ lastTarget = target;
break;
case MouseEvent.MOUSE_CLICKED:
// When we receive a MOUSE_CLICKED, we set the target to the
@@ -174,18 +234,24 @@ class LightweightDispatcher
// This is necessary for the case when the MOUSE_RELEASED has
// caused the original target (like an internal component) go
// away.
+ // This line is the reason why it is not possible to move the
+ // 'lastTarget = target' assignment before the switch-statement.
target = lastTarget;
break;
case MouseEvent.MOUSE_DRAGGED:
+ // We consider only dragTarget for redispatching the event still
+ // we have to act in a way that the newly found target component
+ // was handled.
+ lastTarget = target;
target = dragTarget;
break;
default:
- // Do nothing in other cases.
+ // Only declare current target as the old value in all other
+ // cases.
+ lastTarget = target;
break;
}
- lastTarget = target;
-
if (target != null)
{
Point targetCoordinates =
@@ -195,6 +261,7 @@ class LightweightDispatcher
ev.translatePoint(dx, dy);
ev.setSource(target);
target.dispatchEvent(ev);
+
// We reset the event, so that the normal event dispatching is not
// influenced by this modified event.
ev.setSource(window);
@@ -209,19 +276,36 @@ class LightweightDispatcher
/**
* Finds the actual target for a mouseevent, starting at <code>c</code>.
- * This searches upwards the component hierarchy until it finds a component
- * that has a mouselistener attached.
+ * This searches through the children of the container and finds the first
+ * one which is showing, at the location from the mouse event and has
+ * a MouseListener or MouseMotionListener attached. If no such child component
+ * is found, null is returned.
*
- * @param c the component to start searching from
+ * @param c the container to search through
+ * @param loc the mouse event point
*
- * @return the actual receiver of the mouse event
+ * @return the actual receiver of the mouse event, or null, if no such
+ * component has been found
*/
- private Component findTarget(Component c)
+ private Component findTarget(Container c, Point loc)
{
- Component target = c;
- while (target != null && target.getMouseListeners().length == 0)
+ Component[] children = c.getComponents();
+ Component target = null;
+ if (c != null)
{
- target = target.getParent();
+ Point childLoc;
+ for (int i = 0; i < children.length; i++)
+ {
+ Component child = children[i];
+ childLoc = AWTUtilities.convertPoint(c, loc.x, loc.y, child);
+ if (child.isShowing() && child.contains(childLoc)
+ && (child.getMouseListeners().length > 0
+ || child.getMouseMotionListeners().length > 0))
+ {
+ target = child;
+ break;
+ }
+ }
}
return target;
}
diff --git a/java/awt/TexturePaint.java b/java/awt/TexturePaint.java
index 57d7574c3..387ccb0fd 100644
--- a/java/awt/TexturePaint.java
+++ b/java/awt/TexturePaint.java
@@ -38,42 +38,81 @@ exception statement from your version. */
package java.awt;
-import gnu.classpath.NotImplementedException;
+import gnu.java.awt.java2d.TexturePaintContext;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
-/** STUB CLASS ONLY */
+/**
+ * This class provides a way to fill a Shape with a texture that is
+ * specified by a BufferedImage.
+ */
public class TexturePaint implements Paint
{
private final BufferedImage texture;
private final Rectangle2D anchor;
+
+ /**
+ * Constructor.
+ *
+ * @param texture - the texture
+ * @param anchor - the shape
+ */
public TexturePaint(BufferedImage texture, Rectangle2D anchor)
{
this.texture = texture;
this.anchor = anchor;
}
+
+ /**
+ * Gets the texture image.
+ *
+ * @return the texture
+ */
public BufferedImage getImage()
{
return texture;
}
+
+ /**
+ * Gets the shape anchor.
+ *
+ * @return the shape anchor
+ */
public Rectangle2D getAnchorRect()
{
return anchor;
}
+
+ /**
+ * Creates the context used to paint the texture.
+ *
+ * @param cm - the ColorModel that receives the Paint data. Used only as a hint.
+ * @param deviceBounds - the device space being rendered.
+ * @param userBounds - the user space being rendered
+ * @param xform - the AffineTransform from user space into device space
+ * @param hints - a RenderingHints object that is used to specify how the
+ * pattern is rendered
+ * @return the paint context used to paint the texture
+ */
public PaintContext createContext(ColorModel cm, Rectangle deviceBounds,
Rectangle2D userBounds,
- AffineTransform xform,
- RenderingHints hints)
- throws NotImplementedException
+ AffineTransform xform, RenderingHints hints)
{
- throw new Error("not implemented");
+ // TODO: Maybe add some hook for providing alternative/accelerated
+ // implementations of this.
+ return new TexturePaintContext(this, deviceBounds, userBounds, xform);
}
+
+ /**
+ * Returns the transparency mode.
+ *
+ * @return the transparency mode.
+ */
public int getTransparency()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ return texture.getTransparency();
}
} // class TexturePaint
diff --git a/java/awt/Toolkit.java b/java/awt/Toolkit.java
index 16f1caf85..282e50d2c 100644
--- a/java/awt/Toolkit.java
+++ b/java/awt/Toolkit.java
@@ -544,7 +544,7 @@ public abstract class Toolkit
return ClassLoader.getSystemClassLoader();
}
});
- Class cls = cl.loadClass(toolkit_name);
+ Class cls = Class.forName(toolkit_name, true, cl);
Object obj = cls.newInstance();
if (!(obj instanceof Toolkit))
throw new AWTError(toolkit_name + " is not a subclass of " +
diff --git a/java/awt/Window.java b/java/awt/Window.java
index d9e90c0ea..8bc4715ae 100644
--- a/java/awt/Window.java
+++ b/java/awt/Window.java
@@ -38,8 +38,6 @@ exception statement from your version. */
package java.awt;
-import gnu.classpath.NotImplementedException;
-
import java.awt.event.ComponentEvent;
import java.awt.event.FocusEvent;
import java.awt.event.WindowAdapter;
@@ -132,33 +130,7 @@ public class Window extends Container implements Accessible
// cycle roots.
focusCycleRoot = true;
setLayout(new BorderLayout());
-
- addWindowFocusListener (new WindowAdapter ()
- {
- public void windowGainedFocus (WindowEvent event)
- {
- if (windowFocusOwner != null)
- {
- // FIXME: move this section and the other similar
- // sections in Component into a separate method.
- EventQueue eq = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
- synchronized (eq)
- {
- KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
- Component currentFocusOwner = manager.getGlobalPermanentFocusOwner ();
- if (currentFocusOwner != null)
- {
- eq.postEvent (new FocusEvent (currentFocusOwner, FocusEvent.FOCUS_LOST,
- false, windowFocusOwner));
- eq.postEvent (new FocusEvent (windowFocusOwner, FocusEvent.FOCUS_GAINED,
- false, currentFocusOwner));
- }
- else
- eq.postEvent (new FocusEvent (windowFocusOwner, FocusEvent.FOCUS_GAINED, false));
- }
- }
- }
- });
+ addWindowFocusListener();
GraphicsEnvironment g = GraphicsEnvironment.getLocalGraphicsEnvironment();
graphicsConfiguration = g.getDefaultScreenDevice().getDefaultConfiguration();
@@ -169,7 +141,68 @@ public class Window extends Container implements Accessible
this();
graphicsConfiguration = gc;
}
+
+ private void addWindowFocusListener()
+ {
+ addWindowFocusListener(new WindowAdapter()
+ {
+ public void windowGainedFocus(WindowEvent event)
+ {
+ EventQueue eq = Toolkit.getDefaultToolkit().getSystemEventQueue();
+ if (windowFocusOwner != null)
+ {
+ synchronized (eq)
+ {
+ KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+ Component currentFocusOwner = manager.getGlobalPermanentFocusOwner();
+ if (currentFocusOwner != null)
+ {
+ eq.postEvent(new FocusEvent(currentFocusOwner,
+ FocusEvent.FOCUS_LOST, false,
+ windowFocusOwner));
+ eq.postEvent(new FocusEvent(windowFocusOwner,
+ FocusEvent.FOCUS_GAINED, false,
+ currentFocusOwner));
+ }
+ else
+ eq.postEvent(new FocusEvent(windowFocusOwner,
+ FocusEvent.FOCUS_GAINED, false));
+ }
+ }
+ else
+ eq.postEvent(new FocusEvent(Window.this, FocusEvent.FOCUS_GAINED,
+ false));
+ }
+ public void windowLostFocus(WindowEvent event)
+ {
+ EventQueue eq = Toolkit.getDefaultToolkit().getSystemEventQueue();
+ if (windowFocusOwner != null)
+ {
+ synchronized (eq)
+ {
+ KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+ Component currentFocusOwner = manager.getGlobalPermanentFocusOwner();
+ if (currentFocusOwner != null)
+ {
+ eq.postEvent(new FocusEvent(currentFocusOwner,
+ FocusEvent.FOCUS_GAINED, false,
+ windowFocusOwner));
+ eq.postEvent(new FocusEvent(windowFocusOwner,
+ FocusEvent.FOCUS_LOST, false,
+ currentFocusOwner));
+ }
+ else
+ eq.postEvent(new FocusEvent(windowFocusOwner,
+ FocusEvent.FOCUS_LOST, false));
+ }
+ }
+ else
+ eq.postEvent(new FocusEvent(Window.this, FocusEvent.FOCUS_LOST, false));
+ }
+ });
+ }
+
/**
* Initializes a new instance of <code>Window</code> with the specified
* parent. The window will initially be invisible.
@@ -1046,12 +1079,11 @@ public class Window extends Container implements Accessible
/**
* @since 1.2
*
- * @deprecated
+ * @deprecated replaced by Component.applyComponentOrientation.
*/
public void applyResourceBundle(ResourceBundle rb)
- throws NotImplementedException
{
- throw new Error ("Not implemented");
+ applyComponentOrientation(ComponentOrientation.getOrientation(rb));
}
/**
diff --git a/java/awt/dnd/DragGestureRecognizer.java b/java/awt/dnd/DragGestureRecognizer.java
index 37fde9178..145a24a38 100644
--- a/java/awt/dnd/DragGestureRecognizer.java
+++ b/java/awt/dnd/DragGestureRecognizer.java
@@ -1,5 +1,5 @@
/* DragGestureRecognizer.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002,2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -130,7 +130,7 @@ public abstract class DragGestureRecognizer implements Serializable
public void resetRecognizer()
throws NotImplementedException
{
- throw new Error("not implemented");
+ events = new ArrayList();
}
/**
@@ -154,10 +154,15 @@ public abstract class DragGestureRecognizer implements Serializable
dragGestureListener = null;
}
+ /**
+ * Fires a <code>DragGestureEvent</code> to the DragGestureListener
+ * associated with this object, if there is one.
+ */
protected void fireDragGestureRecognized(int dragAction, Point p)
- throws NotImplementedException
{
- throw new Error("not implemented");
+ if(dragGestureListener != null)
+ dragGestureListener.dragGestureRecognized
+ (new DragGestureEvent(this, dragAction, p, events));
}
protected void appendEvent(InputEvent e)
diff --git a/java/awt/font/GlyphMetrics.java b/java/awt/font/GlyphMetrics.java
index 18aaedc71..0a78d3052 100644
--- a/java/awt/font/GlyphMetrics.java
+++ b/java/awt/font/GlyphMetrics.java
@@ -38,8 +38,6 @@ exception statement from your version. */
package java.awt.font;
-import gnu.classpath.NotImplementedException;
-
import java.awt.geom.Rectangle2D;
/**
@@ -94,16 +92,18 @@ public final class GlyphMetrics
return bounds;
}
- public float getLSB ()
- throws NotImplementedException
+ public float getLSB()
{
- throw new Error ("not implemented");
+ if (horizontal)
+ return (float) bounds.getX();
+ return (float) bounds.getY();
}
- public float getRSB ()
- throws NotImplementedException
+ public float getRSB()
{
- throw new Error ("not implemented");
+ if (horizontal)
+ return (float) (advanceX - (bounds.getX() + bounds.getWidth()));
+ return (float) (advanceY - (bounds.getY() + bounds.getHeight()));
}
public int getType ()
diff --git a/java/awt/font/GlyphVector.java b/java/awt/font/GlyphVector.java
index 8d8a51d68..f4cb01b95 100644
--- a/java/awt/font/GlyphVector.java
+++ b/java/awt/font/GlyphVector.java
@@ -38,8 +38,6 @@ exception statement from your version. */
package java.awt.font;
-import gnu.classpath.NotImplementedException;
-
import java.awt.Font;
import java.awt.Rectangle;
import java.awt.Shape;
@@ -48,6 +46,7 @@ import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
/**
+ * @author Lillian Angel (langel at redhat dot com)
* @author Michael Koch
*/
public abstract class GlyphVector implements Cloneable
@@ -72,16 +71,22 @@ public abstract class GlyphVector implements Cloneable
public abstract FontRenderContext getFontRenderContext ();
public int getGlyphCharIndex (int glyphIndex)
- throws NotImplementedException
{
- throw new Error ("not implemented");
+ return glyphIndex;
}
- public int[] getGlyphCharIndices (int beginGlyphIndex, int numEntries,
- int[] codeReturn)
- throws NotImplementedException
+ public int[] getGlyphCharIndices(int beginGlyphIndex, int numEntries,
+ int[] codeReturn)
{
- throw new Error ("not implemented");
+ if (codeReturn == null)
+ codeReturn = new int[numEntries];
+
+ int i = 0;
+ int j = beginGlyphIndex;
+ while (j < numEntries)
+ codeReturn[i++] = getGlyphCharIndex(j++);
+
+ return codeReturn;
}
public abstract int getGlyphCode (int glyphIndex);
@@ -98,17 +103,27 @@ public abstract class GlyphVector implements Cloneable
public abstract Shape getGlyphOutline (int glyphIndex);
- public Shape getGlyphOutline (int glyphIndex, float x, float y)
- throws NotImplementedException
+ public Shape getGlyphOutline(int glyphIndex, float x, float y)
{
- throw new Error ("not implemented");
+ Shape s = getGlyphOutline(glyphIndex);
+
+ // This is the only way to translate the origin of a shape
+ AffineTransform at = AffineTransform.getTranslateInstance(x, y);
+ return at.createTransformedShape(s);
}
- public Rectangle getGlyphPixelBounds (int index, FontRenderContext renderFRC,
- float x, float y)
- throws NotImplementedException
+ public Rectangle getGlyphPixelBounds(int index, FontRenderContext renderFRC,
+ float x, float y)
{
- throw new Error ("not implemented");
+ Rectangle bounds = new Rectangle();
+ Rectangle2D rect = getGlyphVisualBounds(index).getBounds2D();
+
+ bounds.x = (int) (rect.getX() + x);
+ bounds.y = (int) (rect.getY() + y);
+ bounds.width = (int) rect.getMaxX() - bounds.x;
+ bounds.height = (int) rect.getMaxY() - bounds.y;
+
+ return bounds;
}
public abstract Point2D getGlyphPosition (int glyphIndex);
@@ -121,10 +136,9 @@ public abstract class GlyphVector implements Cloneable
public abstract Shape getGlyphVisualBounds (int glyphIndex);
- public int getLayoutFlags ()
- throws NotImplementedException
+ public int getLayoutFlags()
{
- throw new Error ("not implemented");
+ return 0;
}
public abstract Rectangle2D getLogicalBounds ();
@@ -137,9 +151,16 @@ public abstract class GlyphVector implements Cloneable
public Rectangle getPixelBounds (FontRenderContext renderFRC,
float x, float y)
- throws NotImplementedException
{
- throw new Error ("not implemented");
+ Rectangle bounds = new Rectangle();
+ Rectangle2D rect = getVisualBounds();
+
+ bounds.x = (int) (rect.getX() + x);
+ bounds.y = (int) (rect.getY() + y);
+ bounds.width = (int) rect.getMaxX() - bounds.x;
+ bounds.height = (int) rect.getMaxY() - bounds.y;
+
+ return bounds;
}
public abstract Rectangle2D getVisualBounds ();
diff --git a/java/awt/font/GraphicAttribute.java b/java/awt/font/GraphicAttribute.java
index 107f16dcd..19f781bcc 100644
--- a/java/awt/font/GraphicAttribute.java
+++ b/java/awt/font/GraphicAttribute.java
@@ -38,51 +38,100 @@ exception statement from your version. */
package java.awt.font;
-import gnu.classpath.NotImplementedException;
-
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
/**
+ * This class represents a graphic embedded in text.
+ *
* @author Michael Koch
+ * @author Lillian Angel (langel at redhat dot com)
*/
public abstract class GraphicAttribute
{
- public static final int BOTTOM_ALIGNMENT = -2;
+ public static final int BOTTOM_ALIGNMENT = - 2;
public static final int CENTER_BASELINE = 1;
public static final int HANGING_BASELINE = 2;
public static final int ROMAN_BASELINE = 0;
- public static final int TOP_ALIGNMENT = -1;
+ public static final int TOP_ALIGNMENT = - 1;
private int alignment;
-
- protected GraphicAttribute (int alignment)
+
+ /**
+ * Constructor.
+ *
+ * @param alignment - the alignment to use for the graphic
+ */
+ protected GraphicAttribute(int alignment)
{
+ if (alignment < BOTTOM_ALIGNMENT || alignment > HANGING_BASELINE)
+ throw new IllegalArgumentException("Invalid alignment");
this.alignment = alignment;
}
- public abstract void draw (Graphics2D graphics, float x, float y);
-
- public abstract float getAdvance ();
-
- public final int getAlignment ()
+ /**
+ * Draws the graphic.
+ *
+ * @param graphics - the graphics configuration to use
+ * @param x - the x location
+ * @param y - the y location
+ */
+ public abstract void draw(Graphics2D graphics, float x, float y);
+
+ /**
+ * Gets the distance from the origin of its graphic to the right side of the
+ * bounds of its graphic.
+ *
+ * @return the advance
+ */
+ public abstract float getAdvance();
+
+ /**
+ * Gets the positive distance from the origin of its graphic to the top of
+ * bounds.
+ *
+ * @return the ascent
+ */
+ public abstract float getAscent();
+
+ /**
+ * Gets the distance from the origin of its graphic to the bottom of the bounds.
+ *
+ * @return the descent
+ */
+ public abstract float getDescent();
+
+ /**
+ * Gets the alignment.
+ *
+ * @return the alignment
+ */
+ public final int getAlignment()
{
return alignment;
}
- public abstract float getAscent ();
-
- public Rectangle2D getBounds ()
- throws NotImplementedException
+ /**
+ * Returns a Rectangle2D that encloses the rendered area.
+ * Default bounds is the rectangle (0, -ascent, advance, ascent+descent).
+ *
+ * @return the bounds of the rendered area
+ */
+ public Rectangle2D getBounds()
{
- throw new Error ("not implemented");
+ float asc = getAscent();
+ return new Rectangle2D.Float(0, - asc, getAdvance(), asc + getDescent());
}
- public abstract float getDescent ();
-
- public GlyphJustificationInfo getJustificationInfo ()
- throws NotImplementedException
+ /**
+ * Returns the justification information for this object.
+ *
+ * @return the justification information
+ */
+ public GlyphJustificationInfo getJustificationInfo()
{
- throw new Error ("not implemented");
+ float adv = getAdvance();
+ return new GlyphJustificationInfo(adv, false, 2, adv / 3, adv / 3, false,
+ 1, 0, 0);
}
}
diff --git a/java/awt/font/ImageGraphicAttribute.java b/java/awt/font/ImageGraphicAttribute.java
index c050255ee..3e4fdcf73 100644
--- a/java/awt/font/ImageGraphicAttribute.java
+++ b/java/awt/font/ImageGraphicAttribute.java
@@ -38,82 +38,150 @@ exception statement from your version. */
package java.awt.font;
-import gnu.classpath.NotImplementedException;
-
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.Rectangle2D;
/**
+ * This is an implementation of GraphicAttribute which draws images in a
+ * TextLayout.
+ *
+ * @author Lillian Angel
* @author Michael Koch
*/
-public final class ImageGraphicAttribute extends GraphicAttribute
+public final class ImageGraphicAttribute
+ extends GraphicAttribute
{
private Image image;
-
- public ImageGraphicAttribute (Image image, int alignment)
+ private float originX;
+ private float originY;
+
+ /**
+ * Constucts an instance from the specified Image. The origin is at (0, 0).
+ *
+ * @param image - image to construct from.
+ * @param alignment - the alignment
+ */
+ public ImageGraphicAttribute(Image image, int alignment)
{
- super (alignment);
- this.image = image;
+ this(image, alignment, 0, 0);
}
- public ImageGraphicAttribute (Image image, int alignment, float originX,
- float originY)
- throws NotImplementedException
+ /**
+ * Constucts an instance from the specified Image. The origin is at (originX,
+ * originY).
+ *
+ * @param image - image to construct from
+ * @param alignment - the alignment
+ * @param originX - x point of origin
+ * @param originY - y point of origin
+ */
+ public ImageGraphicAttribute(Image image, int alignment, float originX,
+ float originY)
{
- super (alignment);
+ super(alignment);
this.image = image;
-
- throw new Error ("not implemented");
+ this.originX = originX;
+ this.originY = originY;
}
- public void draw (Graphics2D graphics, float x, float y)
- throws NotImplementedException
+ /**
+ * Draws the image at the specified location, relative to the
+ * origin.
+ *
+ * @param g - the graphics to use to render the image
+ * @param x - the x location
+ * @param y - the y location
+ */
+ public void draw(Graphics2D g, float x, float y)
{
- throw new Error ("not implemented");
+ g.drawImage(image, (int) (x - originX), (int) (y - originY), null);
}
- public boolean equals (Object obj)
+ /**
+ * Compares this to the specified Object
+ *
+ * @param obj - the object to compare
+ * @return true if the obj and this are equivalent
+ */
+ public boolean equals(Object obj)
{
if (! (obj instanceof ImageGraphicAttribute))
return false;
- return equals ((ImageGraphicAttribute) obj);
+ return equals((ImageGraphicAttribute) obj);
}
- public boolean equals (ImageGraphicAttribute rhs)
- throws NotImplementedException
+ /**
+ * Compares this to the ImageGraphicAttribute given, by
+ * comparing all fields and values.
+ *
+ * @param rhs - the ImageGraphicAttribute to compare
+ * @return true if the object given is equivalent to this
+ */
+ public boolean equals(ImageGraphicAttribute rhs)
{
- throw new Error ("not implemented");
+ return ((this == rhs) || ((this.getAscent() == rhs.getAscent())
+ && (this.getAdvance() == rhs.getAdvance())
+ && (this.getAlignment() == rhs.getAlignment())
+ && (this.getBounds().equals(rhs.getBounds()))
+ && (this.getDescent() == rhs.getDescent())
+ && (this.hashCode() == rhs.hashCode())
+ && (this.image.equals(rhs.image))
+ && (this.originX == rhs.originX)
+ && (this.originY == rhs.originY)));
}
- public float getAdvance ()
- throws NotImplementedException
+ /**
+ * Returns distance from the origin to the right edge of the image of this.
+ *
+ * @return the advance
+ */
+ public float getAdvance()
{
- throw new Error ("not implemented");
+ return Math.max(0, image.getWidth(null) - originX);
}
- public float getAscent ()
- throws NotImplementedException
+ /**
+ * Returns the the distance from the top of the image to the origin of this.
+ *
+ * @return the ascent.
+ */
+ public float getAscent()
{
- throw new Error ("not implemented");
+ return Math.max(0, originY);
}
- public Rectangle2D getBounds ()
- throws NotImplementedException
+ /**
+ * Gets the bounds of the object rendered, relative to the position.
+ *
+ * @return the bounds of the object rendered, relative to the position.
+ */
+ public Rectangle2D getBounds()
{
- throw new Error ("not implemented");
+ // This is equivalent to what Sun's JDK returns.
+ // I am not entirely sure why the origin is negative.
+ return new Rectangle2D.Float(- originX, - originY, image.getWidth(null),
+ image.getHeight(null));
}
- public float getDescent ()
- throws NotImplementedException
+ /**
+ * Returns the distance from the origin to the bottom of the image.
+ *
+ * @return the descent
+ */
+ public float getDescent()
{
- throw new Error ("not implemented");
+ return Math.max(0, image.getHeight(null) - originY);
}
- public int hashCode ()
- throws NotImplementedException
+ /**
+ * Gets the hash code for this image.
+ *
+ * @return the hash code
+ */
+ public int hashCode()
{
- throw new Error ("not implemented");
+ return image.hashCode();
}
}
diff --git a/java/awt/font/ShapeGraphicAttribute.java b/java/awt/font/ShapeGraphicAttribute.java
index d5320854c..06814972b 100644
--- a/java/awt/font/ShapeGraphicAttribute.java
+++ b/java/awt/font/ShapeGraphicAttribute.java
@@ -38,74 +38,148 @@ exception statement from your version. */
package java.awt.font;
-import gnu.classpath.NotImplementedException;
-
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Rectangle2D;
+/**
+ * This is an implementation of GraphicAttribute that draws shapes in a TextLayout.
+ *
+ * @author Lillian Angel (langel at redhat dot com)
+ */
public final class ShapeGraphicAttribute extends GraphicAttribute
{
+ /** True if the shape should be filled. */
public static final boolean FILL = false;
+
+ /** True if the shape should be stroked with a 1-pixel wide stroke. */
public static final boolean STROKE = true;
private Shape shape;
private boolean stroke;
+ private Rectangle2D bounds;
- public ShapeGraphicAttribute (Shape shape, int alignment, boolean stroke)
+ /**
+ * Constructor.
+ *
+ * @param shape - the Shape to render. The Shape is rendered with its origin.
+ * @param alignment - the alignment
+ * @param stroke - true if the Shape should be stroked; false if the Shape
+ * should be filled.
+ */
+ public ShapeGraphicAttribute(Shape shape, int alignment, boolean stroke)
{
- super (alignment);
+ super(alignment);
this.shape = shape;
this.stroke = stroke;
+ this.bounds = shape.getBounds2D();
}
- public void draw (Graphics2D graphics, float x, float y)
- throws NotImplementedException
+ /**
+ * Draws the graphic at the given location.
+ *
+ * @param graphics - the graphics to use.
+ * @param x - the x location to draw at.
+ * @param y - the y location to draw at.
+ */
+ public void draw(Graphics2D graphics, float x, float y)
{
- throw new Error ("not implemented");
+ graphics.translate(x, y);
+ if (stroke == STROKE)
+ graphics.draw(shape);
+ else
+ graphics.fill(shape);
+ graphics.translate(- x, - y);
}
- public boolean equals (Object obj)
+ /**
+ * Compares this ShapeGraphicAttribute to obj.
+ *
+ * @param obj - the object to compare.
+ */
+ public boolean equals(Object obj)
{
if (! (obj instanceof ShapeGraphicAttribute))
return false;
- return equals ((ShapeGraphicAttribute) obj);
+ return equals((ShapeGraphicAttribute) obj);
}
- public boolean equals (ShapeGraphicAttribute rhs)
+ /**
+ * Compares this ShapeGraphicAttribute to rhs.
+ *
+ * @param rhs - the ShapeGraphicAttribute to compare.
+ */
+ public boolean equals(ShapeGraphicAttribute rhs)
{
- return (shape.equals (rhs.shape)
- && getAlignment () == rhs.getAlignment ()
- && stroke == rhs.stroke);
+ return (this == rhs || (this.shape.equals(rhs.shape)
+ && getAlignment() == rhs.getAlignment()
+ && stroke == rhs.stroke
+ && getAdvance() == rhs.getAdvance()
+ && getAscent() == rhs.getAscent()
+ && getBounds().equals(rhs.getBounds())
+ && getDescent() == rhs.getDescent()
+ && hashCode() == rhs.hashCode()));
}
- public float getAdvance ()
- throws NotImplementedException
+ /**
+ * Gets the distance from the origin of its Shape to the right side of the
+ * bounds of its Shape.
+ *
+ * @return the advance
+ */
+ public float getAdvance()
{
- throw new Error ("not implemented");
+ return Math.max(0, (float) bounds.getMaxX());
}
- public float getAscent ()
- throws NotImplementedException
+ /**
+ * Gets the positive distance from the origin of its Shape to the top of
+ * bounds.
+ *
+ * @return the ascent
+ */
+ public float getAscent()
{
- throw new Error ("not implemented");
+ return Math.max(0, -(float) bounds.getMinY());
}
- public Rectangle2D getBounds ()
+ /**
+ * Gets the distance from the origin of its Shape to the bottom of the bounds.
+ *
+ * @return the descent
+ */
+ public float getDescent()
{
- return shape.getBounds2D ();
+ return Math.max(0, (float) bounds.getMaxY());
}
- public float getDescent ()
- throws NotImplementedException
+ /**
+ * Returns a Rectangle2D that encloses all of the bits drawn by this shape.
+ *
+ * @return the bounds of the shape.
+ */
+ public Rectangle2D getBounds()
{
- throw new Error ("not implemented");
+ Rectangle2D.Float bounds = new Rectangle2D.Float();
+ bounds.setRect(this.bounds);
+
+ if (stroke == STROKE)
+ {
+ bounds.width++;
+ bounds.height++;
+ }
+
+ return bounds;
}
- public int hashCode ()
+ /**
+ * Gets the hash code.
+ *
+ * @return the hash code.
+ */
+ public int hashCode()
{
- // FIXME: Check what SUN does here
- return shape.hashCode ();
+ return shape.hashCode();
}
}
diff --git a/java/awt/geom/GeneralPath.java b/java/awt/geom/GeneralPath.java
index 15fb8aba8..123833b11 100644
--- a/java/awt/geom/GeneralPath.java
+++ b/java/awt/geom/GeneralPath.java
@@ -1,5 +1,5 @@
/* GeneralPath.java -- represents a shape built from subpaths
- Copyright (C) 2002, 2003, 2004 Free Software Foundation
+ Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation
This file is part of GNU Classpath.
@@ -79,8 +79,16 @@ import java.awt.Shape;
*/
public final class GeneralPath implements Shape, Cloneable
{
- public static final int WIND_EVEN_ODD = PathIterator.WIND_EVEN_ODD;
- public static final int WIND_NON_ZERO = PathIterator.WIND_NON_ZERO;
+ // WORKAROUND for gcj 4.0.x (x < 3)
+ // fully qualify PathIterator constants.
+
+ /** Same constant as {@link PathIterator#WIND_EVEN_ODD}. */
+ public static final int WIND_EVEN_ODD
+ = java.awt.geom.PathIterator.WIND_EVEN_ODD;
+
+ /** Same constant as {@link PathIterator.WIND_NON_ZERO}. */
+ public static final int WIND_NON_ZERO
+ = java.awt.geom.PathIterator.WIND_NON_ZERO;
/** Initial size if not specified. */
private static final int INIT_SIZE = 10;
diff --git a/java/awt/image/ColorModel.java b/java/awt/image/ColorModel.java
index 40307f2b9..e2f5378b4 100644
--- a/java/awt/image/ColorModel.java
+++ b/java/awt/image/ColorModel.java
@@ -92,7 +92,12 @@ public abstract class ColorModel implements Transparency
int transparency;
boolean hasAlpha;
boolean isAlphaPremultiplied;
-
+
+ /**
+ * The standard color model for the common sRGB.
+ */
+ private static final ColorModel S_RGB_MODEL = new SRGBColorModel();
+
static int[] nArray(int value, int times)
{
int[] array = new int[times];
@@ -196,7 +201,7 @@ public abstract class ColorModel implements Transparency
*/
public static ColorModel getRGBdefault()
{
- return new DirectColorModel(32, 0xff0000, 0xff00, 0xff, 0xff000000);
+ return S_RGB_MODEL;
}
public final boolean hasAlpha()
@@ -761,4 +766,56 @@ public abstract class ColorModel implements Transparency
{
return getClass().getName() + "[" + stringParam() + "]";
}
+
+ /**
+ * A color model optimized for standard sRGB.
+ */
+ private static class SRGBColorModel
+ extends DirectColorModel
+ {
+
+ SRGBColorModel()
+ {
+ super(32,0x00FF0000,0x0000FF00,0x000000FF,0xFF000000);
+ }
+
+ public int getAlpha(Object inData)
+ {
+ return ((((int[]) inData)[0]) >> 24) & 0xFF;
+ }
+
+ public int getBlue(Object inData)
+ {
+ return ((((int[]) inData)[0])) & 0xFF;
+ }
+
+ public int getGreen(Object inData)
+ {
+ return ((((int[]) inData)[0]) >> 8) & 0xFF;
+ }
+
+ public int getRed(Object inData)
+ {
+ return ((((int[]) inData)[0]) >> 16) & 0xFF;
+ }
+
+ public int getRGB(Object inData)
+ {
+ return ((int[]) inData)[0];
+ }
+
+ public Object getDataElements(int rgb, Object pixel)
+ {
+ if(pixel == null)
+ {
+ pixel = new int[]{rgb};
+ }
+ else
+ {
+ ((int[]) pixel)[0] = rgb;
+ }
+
+ return pixel;
+ }
+ }
}
diff --git a/java/awt/print/PrinterJob.java b/java/awt/print/PrinterJob.java
index 7f67a6b04..8afada167 100644
--- a/java/awt/print/PrinterJob.java
+++ b/java/awt/print/PrinterJob.java
@@ -38,9 +38,13 @@ exception statement from your version. */
package java.awt.print;
-import java.awt.HeadlessException;
+import gnu.java.awt.print.JavaPrinterJob;
+import java.awt.HeadlessException;
import javax.print.PrintService;
+import javax.print.PrintServiceLookup;
+import javax.print.DocFlavor;
+import javax.print.StreamPrintServiceFactory;
import javax.print.attribute.PrintRequestAttributeSet;
/**
@@ -60,8 +64,7 @@ public abstract class PrinterJob
*/
public static PrinterJob getPrinterJob()
{
- // FIXME: Need to fix this to load a default implementation instance.
- return new NoPrinterJob();
+ return new JavaPrinterJob();
}
/**
@@ -244,13 +247,11 @@ public abstract class PrinterJob
*/
public static PrintService[] lookupPrintServices()
{
- return new PrintService[0];
- // FIXME:
- // Enable this when javax.print has this implemented.
-// return PrintServiceLookup.lookupPrintServices(
-// new DocFlavor("application/x-java-jvm-local-objectref",
-// "java.awt.print.Pageable"),
-// null);
+ return PrintServiceLookup.lookupPrintServices
+ (
+ new DocFlavor("application/x-java-jvm-local-objectref",
+ "java.awt.print.Pageable"),
+ null);
}
/**
@@ -263,8 +264,8 @@ public abstract class PrinterJob
* @return Array of stream print services, could be empty.
* @since 1.4
*/
- // FIXME:
- // Enable when javax.print has StreamPrintServiceFactory
+ // FIXME:
+ // Enable when StreamPrintServiceFactory has lookupStreamServiceFactories
// public static StreamPrintServiceFactory[] lookupStreamPrintServices(String mimeType)
// {
// return StreamPrintServiceFactory.lookupStreamServiceFactories(
@@ -282,7 +283,7 @@ public abstract class PrinterJob
*/
public PrintService getPrintService()
{
- return null;
+ return printer;
}
/**
@@ -297,6 +298,6 @@ public abstract class PrinterJob
public void setPrintService(PrintService service)
throws PrinterException
{
- throw new PrinterException();
+ printer = service;
}
}
diff --git a/java/beans/beancontext/BeanContextSupport.java b/java/beans/beancontext/BeanContextSupport.java
index f3d5ff609..a12c078df 100644
--- a/java/beans/beancontext/BeanContextSupport.java
+++ b/java/beans/beancontext/BeanContextSupport.java
@@ -1,5 +1,5 @@
/* BeanContextSupport.java --
- Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -40,6 +40,7 @@ package java.beans.beancontext;
import gnu.classpath.NotImplementedException;
+import java.beans.Beans;
import java.beans.DesignMode;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
@@ -59,7 +60,12 @@ import java.util.Iterator;
import java.util.Locale;
/**
+ * This is a helper class for implementing a bean context. It is
+ * intended to be used either by subclassing or by calling methods
+ * of this implementation from another.
+ *
* @author Michael Koch
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
* @since 1.2
*/
public class BeanContextSupport extends BeanContextChildSupport
@@ -180,27 +186,102 @@ public class BeanContextSupport extends BeanContextChildSupport
initialize ();
}
- public boolean add (Object targetChild)
+ /**
+ * <p>
+ * Add a child to the bean context. A child can be a simple
+ * <code>Object</code>, a <code>BeanContextChild</code>
+ * or another <code>BeanContext</code>.
+ * </p>
+ * <p>
+ * The children of a <code>BeanContext</code> form a set. As
+ * a result, this method returns <code>false</code> if the given
+ * object is already a child of this context.
+ * </p>
+ * <p>
+ * If the child is a <code>BeanContextChild</code>, or a proxy
+ * for such a child, the <code>setBeanContext()</code> method
+ * is invoked on the child. If this operation is vetoed by the
+ * child, via throwing a <code>PropertyVetoException</code>,
+ * then the current completion state of the <code>add()</code>
+ * operation is rolled back and a <code>IllegalStateException</code>
+ * is thrown. If the <code>BeanContextChild</code> is successfully
+ * added, then the context registers with its
+ * <code>PropertyChangeListener</code> and
+ * <code>VetoableChangeListener</code> for "beanContext" events.
+ * </p>
+ * <p>
+ * If the child implements <code>java.beans.Visibility</code>,
+ * then its ability to use a GUI is set based on that of
+ * this context.
+ * </p>
+ * <p>
+ * A <code>BeanContextMembershipEvent</code> is fired when the
+ * child is successfully added to the bean context.
+ * </p>
+ * <p>
+ * This method is synchronized over the global hierarchy lock.
+ * </p>
+ *
+ * @param targetChild the child to add.
+ * @return false if the child has already been added.
+ * @throws IllegalArgumentException if the child is null.
+ * @throws IllegalStateException if the child vetos the setting
+ * of its context.
+ */
+ public boolean add(Object targetChild)
{
- if (targetChild == null)
- throw new IllegalArgumentException();
-
- BCSChild child;
- synchronized (children)
- {
- if (children.containsKey(targetChild)
- || ! validatePendingAdd(targetChild))
- return false;
- child = createBCSChild(targetChild, beanContextChildPeer);
- children.put(targetChild, child);
- }
- synchronized (targetChild)
+ synchronized (globalHierarchyLock)
{
- childJustAddedHook(targetChild, child);
+ if (targetChild == null)
+ throw new IllegalArgumentException();
+
+ BCSChild child;
+ synchronized (children)
+ {
+ if (children.containsKey(targetChild)
+ || ! validatePendingAdd(targetChild))
+ return false;
+ child = createBCSChild(targetChild, beanContextChildPeer);
+ children.put(targetChild, child);
+ }
+ synchronized (targetChild)
+ {
+ BeanContextChild bcChild = null;
+ if (targetChild instanceof BeanContextChild)
+ bcChild = (BeanContextChild) targetChild;
+ if (targetChild instanceof BeanContextProxy)
+ bcChild = ((BeanContextProxy) targetChild).getBeanContextProxy();
+ if (bcChild != null)
+ try
+ {
+ bcChild.setBeanContext(this);
+ bcChild.addVetoableChangeListener("beanContext", this);
+ bcChild.addPropertyChangeListener("beanContext", this);
+ }
+ catch (PropertyVetoException e)
+ {
+ synchronized (children)
+ {
+ children.remove(targetChild);
+ }
+ throw new IllegalStateException("The child refused to " +
+ "associate itself with " +
+ "this context.", e);
+ }
+ if (targetChild instanceof Visibility)
+ {
+ Visibility visibleChild = (Visibility) targetChild;
+ if (okToUseGui)
+ visibleChild.okToUseGui();
+ else
+ visibleChild.dontUseGui();
+ }
+ childJustAddedHook(targetChild, child);
+ }
+ fireChildrenAdded(new BeanContextMembershipEvent(this,
+ new Object[]{ targetChild }));
+ return true;
}
- fireChildrenAdded(new BeanContextMembershipEvent(this,
- new Object[] { targetChild }));
- return true;
}
public boolean addAll (Collection c)
@@ -219,10 +300,18 @@ public class BeanContextSupport extends BeanContextChildSupport
}
}
- public boolean avoidingGui ()
+ /**
+ * Returns true if this bean needs a GUI
+ * but is being prevented from using one.
+ *
+ * @return true if <code>needsGui()</code>
+ * is true but the bean has been
+ * told not to use it.
+ */
+ public boolean avoidingGui()
throws NotImplementedException
{
- throw new Error ("Not implemented");
+ return needsGui() && (!okToUseGui);
}
protected Iterator bcsChildren ()
@@ -321,10 +410,13 @@ public class BeanContextSupport extends BeanContextChildSupport
throw new Error ("Not implemented");
}
- public void dontUseGui ()
- throws NotImplementedException
+ /**
+ * Informs this bean that is should not make
+ * use of the GUI.
+ */
+ public void dontUseGui()
{
- throw new Error ("Not implemented");
+ okToUseGui = false;
}
protected final void fireChildrenAdded (BeanContextMembershipEvent bcme)
@@ -426,10 +518,20 @@ public class BeanContextSupport extends BeanContextChildSupport
children = new HashMap();
}
+ /**
+ * This is a convenience method for instantiating a bean inside this
+ * context. It delegates to the appropriate method in
+ * <code>java.beans.Beans</code> using the context's classloader.
+ *
+ * @param beanName the name of the class of bean to instantiate.
+ * @throws IOException if an I/O error occurs in loading the class.
+ * @throws ClassNotFoundException if the class, <code>beanName</code>,
+ * can not be found.
+ */
public Object instantiateChild (String beanName)
- throws IOException, ClassNotFoundException, NotImplementedException
+ throws IOException, ClassNotFoundException
{
- throw new Error ("Not implemented");
+ return Beans.instantiate(getClass().getClassLoader(), beanName, this);
}
public boolean isDesignTime ()
@@ -437,6 +539,11 @@ public class BeanContextSupport extends BeanContextChildSupport
return designTime;
}
+ /**
+ * Returns true if this bean context has no children.
+ *
+ * @return true if there are no children.
+ */
public boolean isEmpty ()
{
synchronized (children)
@@ -459,22 +566,38 @@ public class BeanContextSupport extends BeanContextChildSupport
}
}
- public boolean needsGui ()
- throws NotImplementedException
+ /**
+ * Returns false as this bean does not a
+ * GUI for its operation.
+ *
+ * @return false
+ */
+ public boolean needsGui()
{
- throw new Error ("Not implemented");
+ return false;
}
+ /**
+ * Informs this bean that it is okay to make use of
+ * the GUI.
+ */
public void okToUseGui ()
- throws NotImplementedException
{
- throw new Error ("Not implemented");
+ okToUseGui = true;
}
+ /**
+ * Subclasses may use this method to catch property changes
+ * arising from the children of this context. At present,
+ * we just listen for the beans being assigned to a different
+ * context and remove them from here if such an event occurs.
+ *
+ * @param pce the property change event.
+ */
public void propertyChange (PropertyChangeEvent pce)
- throws NotImplementedException
{
- throw new Error ("Not implemented");
+ if (pce.getNewValue() != this)
+ remove(pce.getSource(), false);
}
public final void readChildren (ObjectInputStream ois)
@@ -483,18 +606,100 @@ public class BeanContextSupport extends BeanContextChildSupport
throw new Error ("Not implemented");
}
+ /**
+ * Remove the specified child from the context. This is
+ * the same as calling <code>remove(Object,boolean)</code>
+ * with a request for the <code>setBeanContext()</code> method
+ * of the child to be called (i.e. the second argument is true).
+ *
+ * @param targetChild the child to remove.
+ */
public boolean remove (Object targetChild)
{
return remove(targetChild, true);
}
+ /**
+ * <p>
+ * Removes a child from the bean context. A child can be a simple
+ * <code>Object</code>, a <code>BeanContextChild</code>
+ * or another <code>BeanContext</code>. If the given child is not
+ * a child of this context, this method returns <code>false</code>.
+ * </p>
+ * <p>
+ * If the child is a <code>BeanContextChild</code>, or a proxy
+ * for such a child, the <code>setBeanContext()</code> method
+ * is invoked on the child (if specified). If this operation is vetoed
+ * by the child, via throwing a <code>PropertyVetoException</code>,
+ * then the current completion state of the <code>remove()</code>
+ * operation is rolled back and a <code>IllegalStateException</code>
+ * is thrown. If the <code>BeanContextChild</code> is successfully
+ * removed, then the context deregisters with its
+ * <code>PropertyChangeListener</code> and
+ * <code>VetoableChangeListener</code> for "beanContext" events.
+ * </p>
+ * <p>
+ * A <code>BeanContextMembershipEvent</code> is fired when the
+ * child is successfully removed from the bean context.
+ * </p>
+ * <p>
+ * This method is synchronized over the global hierarchy lock.
+ * </p>
+ *
+ * @param targetChild the child to add.
+ * @param callChildSetBC true if the <code>setBeanContext()</code>
+ * method of the child should be called.
+ * @return false if the child doesn't exist.
+ * @throws IllegalArgumentException if the child is null.
+ * @throws IllegalStateException if the child vetos the setting
+ * of its context.
+ */
protected boolean remove (Object targetChild, boolean callChildSetBC)
- throws NotImplementedException
{
- if (targetChild == null)
- throw new IllegalArgumentException();
-
- throw new Error ("Not implemented");
+ synchronized (globalHierarchyLock)
+ {
+ if (targetChild == null)
+ throw new IllegalArgumentException();
+
+ BCSChild child;
+ synchronized (children)
+ {
+ if (!children.containsKey(targetChild)
+ || !validatePendingRemove(targetChild))
+ return false;
+ child = (BCSChild) children.remove(targetChild);
+ }
+ synchronized (targetChild)
+ {
+ BeanContextChild bcChild = null;
+ if (targetChild instanceof BeanContextChild)
+ bcChild = (BeanContextChild) targetChild;
+ if (targetChild instanceof BeanContextProxy)
+ bcChild = ((BeanContextProxy) targetChild).getBeanContextProxy();
+ if (bcChild != null)
+ try
+ {
+ if (callChildSetBC)
+ bcChild.setBeanContext(null);
+ bcChild.removeVetoableChangeListener("beanContext", this);
+ bcChild.removePropertyChangeListener("beanContext", this);
+ }
+ catch (PropertyVetoException e)
+ {
+ synchronized (children)
+ {
+ children.put(targetChild, child);
+ }
+ throw new IllegalStateException("The child refused to " +
+ "disassociate itself with " +
+ "this context.", e);
+ }
+ childJustRemovedHook(targetChild, child);
+ }
+ fireChildrenRemoved(new BeanContextMembershipEvent(this,
+ new Object[]{ targetChild }));
+ return true;
+ }
}
public boolean removeAll (Collection c)
@@ -578,10 +783,16 @@ public class BeanContextSupport extends BeanContextChildSupport
return true;
}
+ /**
+ * Subclasses may use this method to veto changes arising
+ * from the children of this context.
+ *
+ * @param pce the vetoable property change event fired.
+ */
public void vetoableChange (PropertyChangeEvent pce)
- throws PropertyVetoException, NotImplementedException
+ throws PropertyVetoException
{
- throw new Error ("Not implemented");
+ /* Purposefully left empty */
}
public final void writeChildren (ObjectOutputStream oos)
diff --git a/java/io/ObjectInputStream.java b/java/io/ObjectInputStream.java
index 91832f94e..a37ad73fd 100644
--- a/java/io/ObjectInputStream.java
+++ b/java/io/ObjectInputStream.java
@@ -424,7 +424,23 @@ public class ObjectInputStream extends InputStream
clearHandles();
throw new WriteAbortedException("Exception thrown during writing of stream", e);
}
-
+
+ case TC_ENUM:
+ {
+ /* TC_ENUM classDesc newHandle enumConstantName */
+ if (dump)
+ dumpElementln("ENUM=");
+ ObjectStreamClass osc = (ObjectStreamClass) readObject();
+ String constantName = (String) readObject();
+ if (dump)
+ dumpElementln("CONSTANT NAME = " + constantName);
+ Class clazz = osc.forClass();
+ Enum instance = Enum.valueOf(clazz, constantName);
+ assignNewHandle(instance);
+ ret_val = instance;
+ break;
+ }
+
default:
throw new IOException("Unknown marker on stream: " + marker);
}
diff --git a/java/io/ObjectOutputStream.java b/java/io/ObjectOutputStream.java
index 61f07bc7c..80d196bce 100644
--- a/java/io/ObjectOutputStream.java
+++ b/java/io/ObjectOutputStream.java
@@ -253,7 +253,17 @@ public class ObjectOutputStream extends OutputStream
ObjectStreamClass osc = ObjectStreamClass.lookupForClassObject(clazz);
if (osc == null)
throw new NotSerializableException(clazz.getName());
-
+
+ if (osc.isEnum())
+ {
+ /* TC_ENUM classDesc newHandle enumConstantName */
+ realOutput.writeByte(TC_ENUM);
+ writeObject(osc);
+ assignNewHandle(obj);
+ writeObject(((Enum) obj).name());
+ break;
+ }
+
if ((replacementEnabled || obj instanceof Serializable)
&& ! replaceDone)
{
@@ -432,7 +442,10 @@ public class ObjectOutputStream extends OutputStream
{
realOutput.writeByte(TC_CLASSDESC);
realOutput.writeUTF(osc.getName());
- realOutput.writeLong(osc.getSerialVersionUID());
+ if (osc.isEnum())
+ realOutput.writeLong(0L);
+ else
+ realOutput.writeLong(osc.getSerialVersionUID());
assignNewHandle(osc);
int flags = osc.getFlags();
diff --git a/java/io/ObjectStreamClass.java b/java/io/ObjectStreamClass.java
index 203e4a5ab..abb26d839 100644
--- a/java/io/ObjectStreamClass.java
+++ b/java/io/ObjectStreamClass.java
@@ -219,6 +219,12 @@ public class ObjectStreamClass implements Serializable
return (flags & ObjectStreamConstants.SC_EXTERNALIZABLE) != 0;
}
+ // Returns true iff the class that this ObjectStreamClass represents
+ // implements Externalizable.
+ boolean isEnum()
+ {
+ return (flags & ObjectStreamConstants.SC_ENUM) != 0;
+ }
// Returns the <code>ObjectStreamClass</code> that represents the
// class that is the superclass of the class this
@@ -587,6 +593,9 @@ outer:
if (writeObjectMethod != null)
flags |= ObjectStreamConstants.SC_WRITE_METHOD;
+
+ if (cl.isEnum() || cl == Enum.class)
+ flags |= ObjectStreamConstants.SC_ENUM;
}
@@ -596,7 +605,7 @@ outer:
{
SetAccessibleAction setAccessible = new SetAccessibleAction();
- if (!isSerializable() || isExternalizable())
+ if (!isSerializable() || isExternalizable() || isEnum())
{
fields = NO_FIELDS;
return;
diff --git a/java/io/ObjectStreamConstants.java b/java/io/ObjectStreamConstants.java
index 04cf79bed..a29db2a0e 100644
--- a/java/io/ObjectStreamConstants.java
+++ b/java/io/ObjectStreamConstants.java
@@ -50,8 +50,6 @@ package java.io;
*/
public interface ObjectStreamConstants
{
- // FIXME: Javadoc comment these values.
-
/**
* The serialization stream protocol version 1. This version was
* the default serialization protocol before JDK 1.2.
@@ -70,37 +68,159 @@ public interface ObjectStreamConstants
*/
int PROTOCOL_VERSION_2 = 2;
+ /**
+ * The magic number that is written as part of the stream header.
+ */
short STREAM_MAGIC = (short)0xaced;
+
+ /**
+ * The stream version number that is written as part of the stream header.
+ * Note that this is different from the protocol version that specifies
+ * the data format for the stream.
+ */
short STREAM_VERSION = 5;
+ /**
+ * Token value to designate a <code>null</code> reference in the stream.
+ */
byte TC_NULL = (byte)112; //0x70
+
+ /**
+ * Token value to designate a reference to an already serialized object.
+ */
byte TC_REFERENCE = (byte)113; //0x71
+
+ /**
+ * Token value to designate a class descriptor is next in the stream.
+ */
byte TC_CLASSDESC = (byte)114; //0x72
+
+ /**
+ * Token value to designate a new object is next in the stream.
+ */
byte TC_OBJECT = (byte)115; //0x73
+
+ /**
+ * Token value to designate a new string is next in the stream.
+ */
byte TC_STRING = (byte)116; //0x74
+
+ /**
+ * Token value to designate a new array is next in the stream.
+ */
byte TC_ARRAY = (byte)117; //0x75
+
+ /**
+ * Token reference to designate a reference to a class.
+ */
byte TC_CLASS = (byte)118; //0x76
+
+ /**
+ * Token value to designate a block of primitive data is next in the stream.
+ * The next byte in the stream holds the size of the block (in bytes).
+ */
byte TC_BLOCKDATA = (byte)119; //0x77
+
+ /**
+ * Token value to designate the end of a block of primitve data.
+ */
byte TC_ENDBLOCKDATA = (byte)120; //0x78
+
+ /**
+ * Token value to designate a reset of the stream state.
+ */
byte TC_RESET = (byte)121; //0x79
+
+ /**
+ * Token value to designate a long block of primitive data is next in the
+ * stream. The next long in the stream holds the size of the block
+ * (in bytes).
+ */
byte TC_BLOCKDATALONG = (byte)122; //0x7A
+
+ /**
+ * Token value to designate an exception occured during serialization.
+ */
byte TC_EXCEPTION = (byte)123; //0x7B
+
+ /**
+ * Token value to designate a long string is next in the stream.
+ */
byte TC_LONGSTRING = (byte)124; //0x7C
+
+ /**
+ * Token value to designate a proxy class descriptor is next in the stream.
+ */
byte TC_PROXYCLASSDESC = (byte)125; //0x7D
+ /**
+ * Token value to designate an enum constant is next in the stream.
+ *
+ * @since 1.5
+ */
+ byte TC_ENUM = (byte)126; //0x7E
+
+ /**
+ * The first token value.
+ */
byte TC_BASE = TC_NULL;
- byte TC_MAX = TC_PROXYCLASSDESC;
+
+ /**
+ * The last token value.
+ */
+ byte TC_MAX = TC_ENUM;
+ /**
+ * The first handle that will be assigned to an object, for later references.
+ */
int baseWireHandle = 0x7e0000;
+ /**
+ * Flag used in <code>ObjectStreamClass</code> to designate that the class
+ * defines the <code>writeObject</code> method.
+ */
byte SC_WRITE_METHOD = 0x01;
+
+ /**
+ * Flag used in <code>ObjectStreamClass</code> to designate that the class
+ * is serializeable.
+ */
byte SC_SERIALIZABLE = 0x02;
+
+ /**
+ * Flag used in <code>ObjectStreamClass</code> to designate that the class
+ * is externalizable.
+ */
byte SC_EXTERNALIZABLE = 0x04;
+
+ /**
+ * Flag used in <code>ObjectStreamClass</code> to designate that
+ * externalizable data is written in block data mode.
+ *
+ * @since 1.2
+ */
byte SC_BLOCK_DATA = 0x08;
+ /**
+ * Flag used in <code>ObjectStreamClass</code> to designate that the class
+ * is an enum constant.
+ *
+ * @since 1.5
+ */
+ byte SC_ENUM = 0x10;
+
+ /**
+ * Constant for use with a <code>SecurityManager</code> to check if
+ * substitution of objects is allowed.
+ */
SerializablePermission SUBSTITUTION_PERMISSION
= new SerializablePermission("enableSubstitution");
+ /**
+ * Constant for use with a <code>SecurityManager</code> to check if
+ * overriding of the <code>writeObject</code> and <code>readObject</code>
+ * methods is allowed.
+ */
SerializablePermission SUBCLASS_IMPLEMENTATION_PERMISSION
= new SerializablePermission("enableSubclassImplementation");
}
diff --git a/java/io/OutputStream.java b/java/io/OutputStream.java
index 8608daaa1..e3caa70f1 100644
--- a/java/io/OutputStream.java
+++ b/java/io/OutputStream.java
@@ -1,5 +1,5 @@
/* OutputStream.java -- Base class for byte output streams
- Copyright (C) 1998, 1999, 2001, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2001, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -48,7 +48,7 @@ package java.io;
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey (tromey@cygnus.com)
*/
-public abstract class OutputStream
+public abstract class OutputStream implements Closeable, Flushable
{
/**
* This is the default no-argument constructor for this class. This method
diff --git a/java/lang/SecurityManager.java b/java/lang/SecurityManager.java
index 30ee1be08..999fe83dd 100644
--- a/java/lang/SecurityManager.java
+++ b/java/lang/SecurityManager.java
@@ -421,7 +421,7 @@ public class SecurityManager
public void checkAccess(Thread thread)
{
if (thread.getThreadGroup() != null
- && thread.getThreadGroup().getParent() == null)
+ && thread.getThreadGroup().parent == null)
checkPermission(new RuntimePermission("modifyThread"));
}
@@ -454,7 +454,7 @@ public class SecurityManager
*/
public void checkAccess(ThreadGroup g)
{
- if (g.getParent() == null)
+ if (g.parent == null)
checkPermission(new RuntimePermission("modifyThreadGroup"));
}
diff --git a/java/lang/System.java b/java/lang/System.java
index b538b795b..19278aa32 100644
--- a/java/lang/System.java
+++ b/java/lang/System.java
@@ -222,6 +222,36 @@ public final class System
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()
+ {
+ return VMSystem.nanoTime();
+ }
+
/**
* Copy one array onto another from <code>src[srcStart]</code> ...
* <code>src[srcStart+len-1]</code> to <code>dest[destStart]</code> ...
@@ -319,6 +349,7 @@ public final class System
* <dt>gnu.java.io.encoding_scheme_alias.iso-latin-_?</dt> <dd>8859_?</dd>
* <dt>gnu.java.io.encoding_scheme_alias.latin?</dt> <dd>8859_?</dd>
* <dt>gnu.java.io.encoding_scheme_alias.utf-8</dt> <dd>UTF8</dd>
+ * <dt>gnu.javax.print.server</dt> <dd>Hostname of external CUPS server.</dd>
* </dl>
*
* @return the system properties, will never be null
diff --git a/java/lang/Thread.java b/java/lang/Thread.java
index 23620543a..9be86fa0b 100644
--- a/java/lang/Thread.java
+++ b/java/lang/Thread.java
@@ -38,6 +38,7 @@ exception statement from your version. */
package java.lang;
+import gnu.classpath.VMStackWalker;
import gnu.java.util.WeakIdentityHashMap;
import java.security.Permission;
import java.util.Map;
@@ -131,7 +132,8 @@ public class Thread implements Runnable
/** The context classloader for this Thread. */
private ClassLoader contextClassLoader;
-
+ private boolean contextClassLoaderIsSystemClassLoader;
+
/** This thread's ID. */
private final long threadId;
@@ -248,7 +250,7 @@ public class Thread implements Runnable
*/
public Thread(ThreadGroup group, Runnable target)
{
- this(group, target, "Thread-" + ++numAnonymousThreadsCreated, 0);
+ this(group, target, createAnonymousThreadName(), 0);
}
/**
@@ -347,8 +349,8 @@ public class Thread implements Runnable
if (group == null)
group = current.group;
}
- else if (sm != null)
- sm.checkAccess(group);
+ if (sm != null)
+ sm.checkAccess(group);
this.group = group;
// Use toString hack to detect null.
@@ -364,6 +366,8 @@ public class Thread implements Runnable
priority = current.priority;
daemon = current.daemon;
contextClassLoader = current.contextClassLoader;
+ contextClassLoaderIsSystemClassLoader =
+ current.contextClassLoaderIsSystemClassLoader;
group.addThread(this);
InheritableThreadLocal.newChildThread(this);
@@ -373,6 +377,9 @@ public class Thread implements Runnable
* Used by the VM to create thread objects for threads started outside
* of Java. Note: caller is responsible for adding the thread to
* a group and InheritableThreadLocal.
+ * Note: This constructor should not call any methods that could result
+ * in a call to Thread.currentThread(), because that makes life harder
+ * for the VM.
*
* @param vmThread the native thread
* @param name the thread name or null to use the default naming scheme
@@ -384,16 +391,32 @@ public class Thread implements Runnable
this.vmThread = vmThread;
this.runnable = null;
if (name == null)
- name = "Thread-" + ++numAnonymousThreadsCreated;
+ name = createAnonymousThreadName();
this.name = name;
this.priority = priority;
this.daemon = daemon;
- this.contextClassLoader = ClassLoader.getSystemClassLoader();
+ // By default the context class loader is the system class loader,
+ // we set a flag to signal this because we don't want to call
+ // ClassLoader.getSystemClassLoader() at this point, because on
+ // VMs that lazily create the system class loader that might result
+ // in running user code (when a custom system class loader is specified)
+ // and that user code could call Thread.currentThread().
+ // ClassLoader.getSystemClassLoader() can also return null, if the system
+ // is currently in the process of constructing the system class loader
+ // (and, as above, the constructiong sequence calls Thread.currenThread()).
+ contextClassLoaderIsSystemClassLoader = true;
synchronized (Thread.class)
{
this.threadId = nextThreadId++;
}
+ }
+ /**
+ * Generate a name for an anonymous thread.
+ */
+ private static synchronized String createAnonymousThreadName()
+ {
+ return "Thread-" + ++numAnonymousThreadsCreated;
}
/**
@@ -746,12 +769,18 @@ public class Thread implements Runnable
*/
public synchronized ClassLoader getContextClassLoader()
{
- // Bypass System.getSecurityManager, for bootstrap efficiency.
+ ClassLoader loader = contextClassLoaderIsSystemClassLoader ?
+ ClassLoader.getSystemClassLoader() : contextClassLoader;
+ // Check if we may get the classloader
SecurityManager sm = SecurityManager.current;
- if (sm != null)
- // XXX Don't check this if the caller's class loader is an ancestor.
- sm.checkPermission(new RuntimePermission("getClassLoader"));
- return contextClassLoader;
+ if (loader != null && sm != null)
+ {
+ // Get the calling classloader
+ ClassLoader cl = VMStackWalker.getCallingClassLoader();
+ if (cl != null && !cl.isAncestorOf(loader))
+ sm.checkPermission(new RuntimePermission("getClassLoader"));
+ }
+ return loader;
}
/**
@@ -772,6 +801,7 @@ public class Thread implements Runnable
if (sm != null)
sm.checkPermission(new RuntimePermission("setContextClassLoader"));
this.contextClassLoader = classloader;
+ contextClassLoaderIsSystemClassLoader = false;
}
/**
diff --git a/java/lang/ThreadGroup.java b/java/lang/ThreadGroup.java
index 7fbef88f4..daddf43e3 100644
--- a/java/lang/ThreadGroup.java
+++ b/java/lang/ThreadGroup.java
@@ -66,7 +66,7 @@ public class ThreadGroup implements UncaughtExceptionHandler
static boolean had_uncaught_exception;
/** The parent thread group. */
- private final ThreadGroup parent;
+ final ThreadGroup parent;
/** The group name, non-null. */
final String name;
diff --git a/java/lang/annotation/IncompleteAnnotationException.java b/java/lang/annotation/IncompleteAnnotationException.java
new file mode 100644
index 000000000..a35df0c09
--- /dev/null
+++ b/java/lang/annotation/IncompleteAnnotationException.java
@@ -0,0 +1,106 @@
+/* IncompleteAnnotationException.java - Thrown when annotation has changed
+ Copyright (C) 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.annotation;
+
+/**
+ * Thrown when accessing an element within an annotation which
+ * was added since compilation or serialization took place, and
+ * does not have a default value.
+ *
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+public class IncompleteAnnotationException extends RuntimeException
+{
+
+ /**
+ * Constructs a new <code>IncompleteAnnotationException</code>
+ * which indicates that the element, <code>name</code>, was missing
+ * from the annotation, <code>type</code> at compile time and does
+ * not have a default value.
+ *
+ * @param type the type of annotation from which an element is missing.
+ * @param name the name of the missing element.
+ */
+ public IncompleteAnnotationException(Class type, String name)
+ {
+ this.annotationType = type;
+ this.elementName = name;
+ }
+
+ /**
+ * Returns the class representing the type of annotation
+ * from which an element was missing.
+ *
+ * @return the type of annotation.
+ */
+ public Class annotationType()
+ {
+ return annotationType;
+ }
+
+ /**
+ * Returns the name of the missing annotation element.
+ *
+ * @return the element name.
+ */
+ public String elementName()
+ {
+ return elementName;
+ }
+
+ // Names are chosen from serialization spec.
+
+ /**
+ * The class representing the type of annotation from
+ * which an element was found to be missing.
+ *
+ * @serial the type of the annotation from which an
+ * element was missing.
+ */
+ private Class annotationType;
+
+ /**
+ * The name of the missing element.
+ *
+ * @serial the name of the missing element.
+ */
+ private String elementName;
+
+}
diff --git a/java/lang/management/ManagementFactory.java b/java/lang/management/ManagementFactory.java
new file mode 100644
index 000000000..d070f719c
--- /dev/null
+++ b/java/lang/management/ManagementFactory.java
@@ -0,0 +1,81 @@
+/* ManagementFactory.java - Factory for obtaining system beans.
+ 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 gnu.java.lang.management.OperatingSystemMXBeanImpl;
+
+/**
+ * <p>
+ * Provides access to the system's management beans via a series
+ * of static methods.
+ * </p>
+ * <p>
+ * An instance of a system management bean can be obtained by
+ * using one of the following methods:
+ * </p>
+ * <ol>
+ * <li>Calling the appropriate static method of this factory.
+ * </li>
+ * </ol>
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+public class ManagementFactory
+{
+
+ /**
+ * The operating system management bean.
+ */
+ private static OperatingSystemMXBean osBean;
+
+ /**
+ * Returns the operating system management bean for the
+ * operating system on which the virtual machine is running.
+ *
+ * @return an instance of {@link OperatingSystemMXBean} for
+ * the underlying operating system.
+ */
+ public static OperatingSystemMXBean getOperatingSystemMXBean()
+ {
+ if (osBean == null)
+ osBean = new OperatingSystemMXBeanImpl();
+ return osBean;
+ }
+
+}
diff --git a/java/lang/management/OperatingSystemMXBean.java b/java/lang/management/OperatingSystemMXBean.java
new file mode 100644
index 000000000..74b9ae5a1
--- /dev/null
+++ b/java/lang/management/OperatingSystemMXBean.java
@@ -0,0 +1,103 @@
+/* OperatingSystemMXBean.java - Interface for an operating system 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 java.lang.management;
+
+/**
+ * Provides access to information about the underlying operating
+ * system. Instances of this bean are obtained by calling
+ * {@link ManagementFactory#getOperatingSystemMXBean()}.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+public interface OperatingSystemMXBean
+{
+
+ /**
+ * Returns the name of the underlying system architecture. This
+ * is equivalent to obtaining the <code>os.arch</code> property
+ * via {@link System#getProperty(String)}.
+ *
+ * @return the name of the underlying system architecture on which
+ * the VM is running.
+ * @throws SecurityException if a security manager exists which
+ * prevents access to the name property.
+ * @see java.lang.System#getProperty(String)
+ * @see java.lang.SecurityManager#checkPropertyAccess(String)
+ */
+ String getArch();
+
+ /**
+ * Returns the number of processors currently available to the
+ * virtual machine. This number is subject to change during
+ * execution of the virtual machine, and will always be >= 1.
+ * The call is equivalent to {@link Runtime#availableProcessors()}.
+ *
+ * @return the number of processors available to the VM.
+ */
+ int getAvailableProcessors();
+
+ /**
+ * Returns the name of the underlying operating system. This
+ * is equivalent to obtaining the <code>os.name</code> property
+ * via {@link System#getProperty(String)}.
+ *
+ * @return the name of the operating system on which the VM
+ * is running.
+ * @throws SecurityException if a security manager exists which
+ * prevents access to the name property.
+ * @see java.lang.System#getProperty(String)
+ * @see java.lang.SecurityManager#checkPropertyAccess(String)
+ */
+ String getName();
+
+ /**
+ * Returns the version of the underlying operating system. This
+ * is equivalent to obtaining the <code>os.version</code> property
+ * via {@link System#getProperty(String)}.
+ *
+ * @return the version of the operating system on which the VM
+ * is running.
+ * @throws SecurityException if a security manager exists which
+ * prevents access to the name property.
+ * @see java.lang.System#getProperty(String)
+ * @see java.lang.SecurityManager#checkPropertyAccess(String)
+ */
+ String getVersion();
+
+}
diff --git a/java/lang/management/package.html b/java/lang/management/package.html
new file mode 100644
index 000000000..1b37cc1a5
--- /dev/null
+++ b/java/lang/management/package.html
@@ -0,0 +1,64 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in java.lang.management package.
+ 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. -->
+
+<html>
+<head><title>GNU Classpath - java.lang.management</title></head>
+
+<body>
+
+<p>
+A series of management beans which provide access to information about the
+virtual machine and its underlying operating system.
+</p>
+<p>The following beans are provided:</p>
+<ul>
+<li>
+<span style="font-weight: bold;">{@link java.lang.management.OperatingSystemMXBean} </span>
+&mdash; Information about the underlying operating system.
+</li>
+</ul>
+<h2>Accessing the Beans</h2>
+<p>
+An instance of a bean can be obtained by using one of the following methods:
+</p>
+<ol>
+<li>Calling the appropriate static method of the {@link java.lang.management.ManagementFactory}
+</li>
+</ol>
+</body>
+</html>
diff --git a/java/math/BigDecimal.java b/java/math/BigDecimal.java
index 94b373b04..a58fa931b 100644
--- a/java/math/BigDecimal.java
+++ b/java/math/BigDecimal.java
@@ -1,5 +1,5 @@
/* java.math.BigDecimal -- Arbitrary precision decimals.
- Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2003, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -41,6 +41,7 @@ public class BigDecimal extends Number implements Comparable
{
private BigInteger intVal;
private int scale;
+ private int precision = 0;
private static final long serialVersionUID = 6108874887143696463L;
/**
@@ -48,21 +49,21 @@ public class BigDecimal extends Number implements Comparable
* @since 1.5
*/
public static final BigDecimal ZERO =
- new BigDecimal (BigInteger.valueOf (0), 0);
+ new BigDecimal (BigInteger.ZERO, 0);
/**
* The constant one as a BigDecimal with scale zero.
* @since 1.5
*/
public static final BigDecimal ONE =
- new BigDecimal (BigInteger.valueOf (1), 0);
+ new BigDecimal (BigInteger.ONE, 0);
/**
* The constant ten as a BigDecimal with scale zero.
* @since 1.5
*/
public static final BigDecimal TEN =
- new BigDecimal (BigInteger.valueOf (10), 0);
+ new BigDecimal (BigInteger.TEN, 0);
public static final int ROUND_UP = 0;
public static final int ROUND_DOWN = 1;
@@ -73,19 +74,181 @@ public class BigDecimal extends Number implements Comparable
public static final int ROUND_HALF_EVEN = 6;
public static final int ROUND_UNNECESSARY = 7;
+ /**
+ * Constructs a new BigDecimal whose unscaled value is val and whose
+ * scale is zero.
+ * @param val the value of the new BigDecimal
+ * @since 1.5
+ */
+ public BigDecimal (int val)
+ {
+ this.intVal = BigInteger.valueOf(val);
+ this.scale = 0;
+ }
+
+ /**
+ * Constructs a BigDecimal using the BigDecimal(int) constructor and then
+ * rounds according to the MathContext.
+ * @param val the value for the initial (unrounded) BigDecimal
+ * @param mc the MathContext specifying the rounding
+ * @throws ArithmeticException if the result is inexact but the rounding type
+ * is RoundingMode.UNNECESSARY
+ * @since 1.5
+ */
+ public BigDecimal (int val, MathContext mc)
+ {
+ this (val);
+ if (mc.getPrecision() != 0)
+ {
+ BigDecimal result = this.round(mc);
+ this.intVal = result.intVal;
+ this.scale = result.scale;
+ this.precision = result.precision;
+ }
+ }
+
+ /**
+ * Constructs a new BigDecimal whose unscaled value is val and whose
+ * scale is zero.
+ * @param val the value of the new BigDecimal
+ */
+ public BigDecimal (long val)
+ {
+ this.intVal = BigInteger.valueOf(val);
+ this.scale = 0;
+ }
+
+ /**
+ * Constructs a BigDecimal from the long in the same way as BigDecimal(long)
+ * and then rounds according to the MathContext.
+ * @param val the long from which we create the initial BigDecimal
+ * @param mc the MathContext that specifies the rounding behaviour
+ * @throws ArithmeticException if the result is inexact but the rounding type
+ * is RoundingMode.UNNECESSARY
+ * @since 1.5
+ */
+ public BigDecimal (long val, MathContext mc)
+ {
+ this(val);
+ if (mc.getPrecision() != 0)
+ {
+ BigDecimal result = this.round(mc);
+ this.intVal = result.intVal;
+ this.scale = result.scale;
+ this.precision = result.precision;
+ }
+ }
+
+ /**
+ * Constructs a BigDecimal whose value is given by num rounded according to
+ * mc. Since num is already a BigInteger, the rounding refers only to the
+ * precision setting in mc, if mc.getPrecision() returns an int lower than
+ * the number of digits in num, then rounding is necessary.
+ * @param num the unscaledValue, before rounding
+ * @param mc the MathContext that specifies the precision
+ * @throws ArithmeticException if the result is inexact but the rounding type
+ * is RoundingMode.UNNECESSARY
+ * * @since 1.5
+ */
+ public BigDecimal (BigInteger num, MathContext mc)
+ {
+ this (num, 0);
+ if (mc.getPrecision() != 0)
+ {
+ BigDecimal result = this.round(mc);
+ this.intVal = result.intVal;
+ this.scale = result.scale;
+ this.precision = result.precision;
+ }
+ }
+
+ /**
+ * Constructs a BigDecimal from the String val according to the same
+ * rules as the BigDecimal(String) constructor and then rounds
+ * according to the MathContext mc.
+ * @param val the String from which we construct the initial BigDecimal
+ * @param mc the MathContext that specifies the rounding
+ * @throws ArithmeticException if the result is inexact but the rounding type
+ * is RoundingMode.UNNECESSARY
+ * @since 1.5
+ */
+ public BigDecimal (String val, MathContext mc)
+ {
+ this (val);
+ if (mc.getPrecision() != 0)
+ {
+ BigDecimal result = this.round(mc);
+ this.intVal = result.intVal;
+ this.scale = result.scale;
+ this.precision = result.precision;
+ }
+ }
+
+ /**
+ * Constructs a BigDecimal whose unscaled value is num and whose
+ * scale is zero.
+ * @param num the value of the new BigDecimal
+ */
public BigDecimal (BigInteger num)
{
this (num, 0);
}
- public BigDecimal (BigInteger num, int scale) throws NumberFormatException
+ /**
+ * Constructs a BigDecimal whose unscaled value is num and whose
+ * scale is scale.
+ * @param num
+ * @param scale
+ */
+ public BigDecimal (BigInteger num, int scale)
{
- if (scale < 0)
- throw new NumberFormatException ("scale of " + scale + " is < 0");
this.intVal = num;
this.scale = scale;
}
+
+ /**
+ * Constructs a BigDecimal using the BigDecimal(BigInteger, int)
+ * constructor and then rounds according to the MathContext.
+ * @param num the unscaled value of the unrounded BigDecimal
+ * @param scale the scale of the unrounded BigDecimal
+ * @param mc the MathContext specifying the rounding
+ * @throws ArithmeticException if the result is inexact but the rounding type
+ * is RoundingMode.UNNECESSARY
+ * @since 1.5
+ */
+ public BigDecimal (BigInteger num, int scale, MathContext mc)
+ {
+ this (num, scale);
+ if (mc.getPrecision() != 0)
+ {
+ BigDecimal result = this.round(mc);
+ this.intVal = result.intVal;
+ this.scale = result.scale;
+ this.precision = result.precision;
+ }
+ }
+ /**
+ * Constructs a BigDecimal in the same way as BigDecimal(double) and then
+ * rounds according to the MathContext.
+ * @param num the double from which the initial BigDecimal is created
+ * @param mc the MathContext that specifies the rounding behaviour
+ * @throws ArithmeticException if the result is inexact but the rounding type
+ * is RoundingMode.UNNECESSARY
+ * @since 1.5
+ */
+ public BigDecimal (double num, MathContext mc)
+ {
+ this (num);
+ if (mc.getPrecision() != 0)
+ {
+ BigDecimal result = this.round(mc);
+ this.intVal = result.intVal;
+ this.scale = result.scale;
+ this.precision = result.precision;
+ }
+ }
+
public BigDecimal (double num) throws NumberFormatException
{
if (Double.isInfinite (num) || Double.isNaN (num))
@@ -136,6 +299,209 @@ public class BigDecimal extends Number implements Comparable
}
}
+ /**
+ * Constructs a BigDecimal from the char subarray and rounding
+ * according to the MathContext.
+ * @param in the char array
+ * @param offset the start of the subarray
+ * @param len the length of the subarray
+ * @param mc the MathContext for rounding
+ * @throws NumberFormatException if the char subarray is not a valid
+ * BigDecimal representation
+ * @throws ArithmeticException if the result is inexact but the rounding
+ * mode is RoundingMode.UNNECESSARY
+ * @since 1.5
+ */
+ public BigDecimal(char[] in, int offset, int len, MathContext mc)
+ {
+ this(in, offset, len);
+ // If mc has precision other than zero then we must round.
+ if (mc.getPrecision() != 0)
+ {
+ BigDecimal temp = this.round(mc);
+ this.intVal = temp.intVal;
+ this.scale = temp.scale;
+ this.precision = temp.precision;
+ }
+ }
+
+ /**
+ * Constructs a BigDecimal from the char array and rounding according
+ * to the MathContext.
+ * @param in the char array
+ * @param mc the MathContext
+ * @throws NumberFormatException if <code>in</code> is not a valid BigDecimal
+ * representation
+ * @throws ArithmeticException if the result is inexact but the rounding mode
+ * is RoundingMode.UNNECESSARY
+ * @since 1.5
+ */
+ public BigDecimal(char[] in, MathContext mc)
+ {
+ this(in, 0, in.length);
+ // If mc has precision other than zero then we must round.
+ if (mc.getPrecision() != 0)
+ {
+ BigDecimal temp = this.round(mc);
+ this.intVal = temp.intVal;
+ this.scale = temp.scale;
+ this.precision = temp.precision;
+ }
+ }
+
+ /**
+ * Constructs a BigDecimal from the given char array, accepting the same
+ * sequence of characters as the BigDecimal(String) constructor.
+ * @param in the char array
+ * @throws NumberFormatException if <code>in</code> is not a valid BigDecimal
+ * representation
+ * @since 1.5
+ */
+ public BigDecimal(char[] in)
+ {
+ this(in, 0, in.length);
+ }
+
+ /**
+ * Constructs a BigDecimal from a char subarray, accepting the same sequence
+ * of characters as the BigDecimal(String) constructor.
+ * @param in the char array
+ * @param offset the start of the subarray
+ * @param len the length of the subarray
+ * @throws NumberFormatException if <code>in</code> is not a valid
+ * BigDecimal representation.
+ * @since 1.5
+ */
+ public BigDecimal(char[] in, int offset, int len)
+ {
+ // start is the index into the char array where the significand starts
+ int start = offset;
+ // end is one greater than the index of the last character used
+ int end = offset + len;
+ // point is the index into the char array where the exponent starts
+ // (or, if there is no exponent, this is equal to end)
+ int point = offset;
+ // dot is the index into the char array where the decimal point is
+ // found, or -1 if there is no decimal point
+ int dot = -1;
+
+ // The following examples show what these variables mean. Note that
+ // point and dot don't yet have the correct values, they will be
+ // properly assigned in a loop later on in this method.
+ //
+ // Example 1
+ //
+ // + 1 0 2 . 4 6 9
+ // __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
+ //
+ // offset = 2, len = 8, start = 3, dot = 6, point = end = 10
+ //
+ // Example 2
+ //
+ // + 2 3 4 . 6 1 3 E - 1
+ // __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
+ //
+ // offset = 2, len = 11, start = 3, dot = 6, point = 10, end = 13
+ //
+ // Example 3
+ //
+ // - 1 2 3 4 5 e 7
+ // __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
+ //
+ // offset = 2, len = 8, start = 3, dot = -1, point = 8, end = 10
+
+ // Determine the sign of the number.
+ boolean negative = false;
+ if (in[offset] == '+')
+ {
+ ++start;
+ ++point;
+ }
+ else if (in[offset] == '-')
+ {
+ ++start;
+ ++point;
+ negative = true;
+ }
+
+ // Check each character looking for the decimal point and the
+ // start of the exponent.
+ while (point < end)
+ {
+ char c = in[point];
+ if (c == '.')
+ {
+ // If dot != -1 then we've seen more than one decimal point.
+ if (dot != -1)
+ throw new NumberFormatException("multiple `.'s in number");
+ dot = point;
+ }
+ // Break when we reach the start of the exponent.
+ else if (c == 'e' || c == 'E')
+ break;
+ // Throw an exception if the character was not a decimal or an
+ // exponent and is not a digit.
+ else if (!Character.isDigit(c))
+ throw new NumberFormatException("unrecognized character at " + point
+ + ": " + c);
+ ++point;
+ }
+
+ // val is a StringBuilder from which we'll create a BigInteger
+ // which will be the unscaled value for this BigDecimal
+ StringBuilder val = new StringBuilder(point - start - 1);
+ if (dot != -1)
+ {
+ // If there was a decimal we must combine the two parts that
+ // contain only digits and we must set the scale properly.
+ val.append(in, start, dot - start);
+ val.append(in, dot + 1, point - dot - 1);
+ scale = point - 1 - dot;
+ }
+ else
+ {
+ // If there was no decimal then the unscaled value is just the number
+ // formed from all the digits and the scale is zero.
+ val.append(in, start, point - start);
+ scale = 0;
+ }
+ if (val.length() == 0)
+ throw new NumberFormatException("no digits seen");
+
+ // Prepend a negative sign if necessary.
+ if (negative)
+ val.insert(0, '-');
+ intVal = new BigInteger(val.toString());
+
+ // Now parse exponent.
+ // If point < end that means we broke out of the previous loop when we
+ // saw an 'e' or an 'E'.
+ if (point < end)
+ {
+ point++;
+ // Ignore a '+' sign.
+ if (in[point] == '+')
+ point++;
+
+ // Throw an exception if there were no digits found after the 'e'
+ // or 'E'.
+ if (point >= end)
+ throw new NumberFormatException("no exponent following e or E");
+
+ try
+ {
+ // Adjust the scale according to the exponent.
+ // Remember that the value of a BigDecimal is
+ // unscaledValue x Math.pow(10, -scale)
+ scale -= Integer.parseInt(new String(in, point, end - point));
+ }
+ catch (NumberFormatException ex)
+ {
+ throw new NumberFormatException("malformed exponent");
+ }
+ }
+ }
+
public BigDecimal (String num) throws NumberFormatException
{
int len = num.length();
@@ -199,18 +565,8 @@ public class BigDecimal extends Number implements Comparable
throw new NumberFormatException ("no exponent following e or E");
try
- {
- int exp = Integer.parseInt (num.substring (point));
- exp -= scale;
- if (signum () == 0)
- scale = 0;
- else if (exp > 0)
- {
- intVal = intVal.multiply (BigInteger.valueOf (10).pow (exp));
- scale = 0;
- }
- else
- scale = - exp;
+ {
+ scale -= Integer.parseInt (num.substring (point));
}
catch (NumberFormatException ex)
{
@@ -247,29 +603,74 @@ public class BigDecimal extends Number implements Comparable
BigInteger op1 = intVal;
BigInteger op2 = val.intVal;
if (scale < val.scale)
- op1 = op1.multiply (BigInteger.valueOf (10).pow (val.scale - scale));
+ op1 = op1.multiply (BigInteger.TEN.pow (val.scale - scale));
else if (scale > val.scale)
- op2 = op2.multiply (BigInteger.valueOf (10).pow (scale - val.scale));
+ op2 = op2.multiply (BigInteger.TEN.pow (scale - val.scale));
return new BigDecimal (op1.add (op2), Math.max (scale, val.scale));
}
+
+ /**
+ * Returns a BigDecimal whose value is found first by calling the
+ * method add(val) and then by rounding according to the MathContext mc.
+ * @param val the augend
+ * @param mc the MathContext for rounding
+ * @throws ArithmeticException if the value is inexact but the rounding is
+ * RoundingMode.UNNECESSARY
+ * @return <code>this</code> + <code>val</code>, rounded if need be
+ * @since 1.5
+ */
+ public BigDecimal add (BigDecimal val, MathContext mc)
+ {
+ return add(val).round(mc);
+ }
public BigDecimal subtract (BigDecimal val)
{
return this.add(val.negate());
}
+ /**
+ * Returns a BigDecimal whose value is found first by calling the
+ * method subtract(val) and then by rounding according to the MathContext mc.
+ * @param val the subtrahend
+ * @param mc the MathContext for rounding
+ * @throws ArithmeticException if the value is inexact but the rounding is
+ * RoundingMode.UNNECESSARY
+ * @return <code>this</code> - <code>val</code>, rounded if need be
+ * @since 1.5
+ */
+ public BigDecimal subtract (BigDecimal val, MathContext mc)
+ {
+ return subtract(val).round(mc);
+ }
+
public BigDecimal multiply (BigDecimal val)
{
return new BigDecimal (intVal.multiply (val.intVal), scale + val.scale);
}
+
+ /**
+ * Returns a BigDecimal whose value is (this x val) before it is rounded
+ * according to the MathContext mc.
+ * @param val the multiplicand
+ * @param mc the MathContext for rounding
+ * @return a new BigDecimal with value approximately (this x val)
+ * @throws ArithmeticException if the value is inexact but the rounding mode
+ * is RoundingMode.UNNECESSARY
+ * @since 1.5
+ */
+ public BigDecimal multiply (BigDecimal val, MathContext mc)
+ {
+ return multiply(val).round(mc);
+ }
public BigDecimal divide (BigDecimal val, int roundingMode)
throws ArithmeticException, IllegalArgumentException
{
return divide (val, scale, roundingMode);
}
-
+
public BigDecimal divide(BigDecimal val, int newScale, int roundingMode)
throws ArithmeticException, IllegalArgumentException
{
@@ -277,9 +678,6 @@ public class BigDecimal extends Number implements Comparable
throw
new IllegalArgumentException("illegal rounding mode: " + roundingMode);
- if (newScale < 0)
- throw new ArithmeticException ("scale is negative: " + newScale);
-
if (intVal.signum () == 0) // handle special case of 0.0/0.0
return newScale == 0 ? ZERO : new BigDecimal (ZERO.intVal, newScale);
@@ -290,11 +688,11 @@ public class BigDecimal extends Number implements Comparable
{
// Effectively increase the scale of val to avoid an
// ArithmeticException for a negative power.
- valIntVal = valIntVal.multiply (BigInteger.valueOf (10).pow (-power));
+ valIntVal = valIntVal.multiply (BigInteger.TEN.pow (-power));
power = 0;
}
- BigInteger dividend = intVal.multiply (BigInteger.valueOf (10).pow (power));
+ BigInteger dividend = intVal.multiply (BigInteger.TEN.pow (power));
BigInteger parts[] = dividend.divideAndRemainder (valIntVal);
@@ -303,7 +701,7 @@ public class BigDecimal extends Number implements Comparable
return new BigDecimal (unrounded, newScale);
if (roundingMode == ROUND_UNNECESSARY)
- throw new ArithmeticException ("newScale is not large enough");
+ throw new ArithmeticException ("Rounding necessary");
int sign = intVal.signum () * valIntVal.signum ();
@@ -348,16 +746,78 @@ public class BigDecimal extends Number implements Comparable
// roundingMode == ROUND_DOWN
return new BigDecimal (unrounded, newScale);
}
+
+ /**
+ * Returns a BigDecimal whose value is the remainder in the quotient
+ * this / val. This is obtained by
+ * subtract(divideToIntegralValue(val).multiply(val)).
+ * @param val the divisor
+ * @return a BigDecimal whose value is the remainder
+ * @throws ArithmeticException if val == 0
+ * @since 1.5
+ */
+ public BigDecimal remainder(BigDecimal val)
+ {
+ return subtract(divideToIntegralValue(val).multiply(val));
+ }
+
+ /**
+ * Returns a BigDecimal array, the first element of which is the integer part
+ * of this / val, and the second element of which is the remainder of
+ * that quotient.
+ * @param val the divisor
+ * @return the above described BigDecimal array
+ * @throws ArithmeticException if val == 0
+ * @since 1.5
+ */
+ public BigDecimal[] divideAndRemainder(BigDecimal val)
+ {
+ BigDecimal[] result = new BigDecimal[2];
+ result[0] = divideToIntegralValue(val);
+ result[1] = subtract(result[0].multiply(val));
+ return result;
+ }
+
+ /**
+ * Returns a BigDecimal whose value is the integer part of the quotient
+ * this / val. The preferred scale is this.scale - val.scale.
+ * @param val the divisor
+ * @return a BigDecimal whose value is the integer part of this / val.
+ * @throws ArithmeticException if val == 0
+ * @since 1.5
+ */
+ public BigDecimal divideToIntegralValue(BigDecimal val)
+ {
+ return divide(val, ROUND_DOWN).floor().setScale(scale - val.scale, ROUND_DOWN);
+ }
+
+ /**
+ * Mutates this BigDecimal into one with no fractional part, whose value is
+ * equal to the largest integer that is <= to this BigDecimal. Note that
+ * since this method is private it is okay to mutate this BigDecimal.
+ * @return the BigDecimal obtained through the floor operation on this
+ * BigDecimal.
+ */
+ private BigDecimal floor()
+ {
+ if (scale <= 0)
+ return this;
+ String intValStr = intVal.toString();
+ intValStr = intValStr.substring(0, intValStr.length() - scale);
+ intVal = new BigInteger(intValStr).multiply(BigInteger.TEN.pow(scale));
+ return this;
+ }
- public int compareTo (BigDecimal val)
+ public int compareTo (Object obj)
{
+ BigDecimal val = (BigDecimal) obj;
if (scale == val.scale)
return intVal.compareTo (val.intVal);
BigInteger thisParts[] =
- intVal.divideAndRemainder (BigInteger.valueOf (10).pow (scale));
+ intVal.divideAndRemainder (BigInteger.TEN.pow (scale));
BigInteger valParts[] =
- val.intVal.divideAndRemainder (BigInteger.valueOf (10).pow (val.scale));
+ val.intVal.divideAndRemainder (BigInteger.TEN.pow (val.scale));
int compare;
if ((compare = thisParts[0].compareTo (valParts[0])) != 0)
@@ -377,11 +837,6 @@ public class BigDecimal extends Number implements Comparable
return thisParts[1].compareTo (valParts[1]);
}
- public int compareTo (Object val)
- {
- return(compareTo((BigDecimal)val));
- }
-
public boolean equals (Object o)
{
return (o instanceof BigDecimal
@@ -430,7 +885,7 @@ public class BigDecimal extends Number implements Comparable
return new BigDecimal (intVal, scale - n);
return new BigDecimal (intVal.multiply
- (BigInteger.valueOf (10).pow (n - scale)), 0);
+ (BigInteger.TEN.pow (n - scale)), 0);
}
public int signum ()
@@ -457,21 +912,367 @@ public class BigDecimal extends Number implements Comparable
{
return new BigDecimal (intVal.negate (), scale);
}
+
+ /**
+ * Returns a BigDecimal whose value is found first by negating this via
+ * the negate() method, then by rounding according to the MathContext mc.
+ * @param mc the MathContext for rounding
+ * @return a BigDecimal whose value is approximately (-this)
+ * @throws ArithmeticException if the value is inexact but the rounding mode
+ * is RoundingMode.UNNECESSARY
+ * @since 1.5
+ */
+ public BigDecimal negate(MathContext mc)
+ {
+ BigDecimal result = negate();
+ if (mc.getPrecision() != 0)
+ result = result.round(mc);
+ return result;
+ }
+
+ /**
+ * Returns this BigDecimal. This is included for symmetry with the
+ * method negate().
+ * @return this
+ * @since 1.5
+ */
+ public BigDecimal plus()
+ {
+ return this;
+ }
+
+ /**
+ * Returns a BigDecimal whose value is found by rounding <code>this</code>
+ * according to the MathContext. This is the same as round(MathContext).
+ * @param mc the MathContext for rounding
+ * @return a BigDecimal whose value is <code>this</code> before being rounded
+ * @throws ArithmeticException if the value is inexact but the rounding mode
+ * is RoundingMode.UNNECESSARY
+ * @since 1.5
+ */
+ public BigDecimal plus(MathContext mc)
+ {
+ return round(mc);
+ }
+
+ /**
+ * Returns a BigDecimal which is this BigDecimal rounded according to the
+ * MathContext rounding settings.
+ * @param mc the MathContext that tells us how to round
+ * @return the rounded BigDecimal
+ */
+ public BigDecimal round(MathContext mc)
+ {
+ int mcPrecision = mc.getPrecision();
+ int numToChop = precision() - mcPrecision;
+ // If mc specifies not to chop any digits or if we've already chopped
+ // enough digits (say by using a MathContext in the constructor for this
+ // BigDecimal) then just return this.
+ if (mcPrecision == 0 || numToChop <= 0)
+ return this;
+
+ // Make a new BigDecimal which is the correct power of 10 to chop off
+ // the required number of digits and then call divide.
+ BigDecimal div = new BigDecimal(BigInteger.TEN.pow(numToChop));
+ BigDecimal rounded = divide(div, scale, 4);
+ rounded.scale -= numToChop;
+ rounded.precision = mcPrecision;
+ return rounded;
+ }
+
+ /**
+ * Returns the precision of this BigDecimal (the number of digits in the
+ * unscaled value). The precision of a zero value is 1.
+ * @return the number of digits in the unscaled value, or 1 if the value
+ * is zero.
+ */
+ public int precision()
+ {
+ if (precision == 0)
+ {
+ if (intVal.compareTo(BigInteger.TEN.pow(18)) == 1)
+ precision = numDigitsInBigInteger(intVal);
+ else
+ precision = numDigitsInLong(intVal.longValue());
+ }
+ return precision;
+ }
+
+ /**
+ * This method is used to determine the precision of BigIntegers with 19 or
+ * more digits.
+ * @param b the BigInteger
+ * @return the number of digits in <code>b</code>
+ */
+ int numDigitsInBigInteger(BigInteger b)
+ {
+ int i = 19;
+ BigInteger comp = BigInteger.TEN.pow(i);
+ while (b.compareTo(comp) >= 0)
+ comp = BigInteger.TEN.pow(++i);
+
+ return i;
+ }
+
+ /**
+ * This method determines the number of digits in the long value l.
+ * @param l1 the long value
+ * @return the number of digits in l
+ */
+ private static int numDigitsInLong(long l1)
+ {
+ long l = l1 >= 0 ? l1 : -l1;
+ // We divide up the range in a binary fashion, this first if
+ // takes care of numbers with 1 to 9 digits.
+ if (l < 1000000000L)
+ {
+ // This if is for numbers with 1 to 5 digits.
+ if (l < 100000L)
+ {
+ if (l < 100L)
+ return (l < 10L) ? 1 : 2;
+ if (l < 10000L)
+ return (l < 1000L) ? 3 : 4;
+ return 5;
+ }
+ // Here we handle numbers with 6 to 9 digits.
+ if (l < 10000000L)
+ return (l < 1000000L) ? 6 : 7;
+ return (l < 100000000L) ? 8 : 9;
+ }
+ // If we are at this point that means we didn't enter the loop for
+ // numbers with 1 to 9 digits, so our number has 10 to 19 digits.
+ // This first if handles numbers with 10 to 14 digits.
+ if (l < 100000000000000L)
+ {
+ // This handles numbers with 10 to 12 digits.
+ if (l < 1000000000000L)
+ {
+ if (l < 100000000000L)
+ return (l < 10000000000L) ? 10 : 11;
+ return 12;
+ }
+ // This handles numbers with 13 or 14 digits.
+ return (l < 10000000000000L) ? 13 : 14;
+ }
+ // Finally we handle numbers with 15 to 19 digits.
+ if (l < 100000000000000000L)
+ {
+ // 15 to 17 digits.
+ if (l < 1000000000000000L)
+ return 15;
+ return (l < 10000000000000000L) ? 16 : 17;
+ }
+ // 18 or 19 digits.
+ return (l < 1000000000000000000L) ? 18 : 19;
+ }
+
+ /**
+ * Returns the String representation of this BigDecimal, using scientific
+ * notation if necessary. The following steps are taken to generate
+ * the result:
+ *
+ * 1. the BigInteger unscaledValue's toString method is called and if
+ * <code>scale == 0<code> is returned.
+ * 2. an <code>int adjExp</code> is created which is equal to the negation
+ * of <code>scale</code> plus the number of digits in the unscaled value,
+ * minus one.
+ * 3. if <code>scale >= 0 && adjExp >= -6</code> then we represent this
+ * BigDecimal without scientific notation. A decimal is added if the
+ * scale is positive and zeros are prepended as necessary.
+ * 4. if scale is negative or adjExp is less than -6 we use scientific
+ * notation. If the unscaled value has more than one digit, a decimal
+ * as inserted after the first digit, the character 'E' is appended
+ * and adjExp is appended.
+ */
+ public String toString()
+ {
+ // bigStr is the String representation of the unscaled value. If
+ // scale is zero we simply return this.
+ String bigStr = intVal.toString();
+ if (scale == 0)
+ return bigStr;
+
+ // This is the adjusted exponent described above.
+ int adjExp = -scale + (numDigitsInLong(intVal.longValue()) - 1);
+ StringBuilder val = new StringBuilder();
+
+ if (scale >= 0 && adjExp >= -6)
+ {
+ // Convert to character form without scientific notation.
+ boolean negative = (bigStr.charAt(0) == '-');
+ int point = bigStr.length() - scale - (negative ? 1 : 0);
+ if (point <= 0)
+ {
+ // Zeros need to be prepended to the StringBuilder.
+ if (negative)
+ val.append('-');
+ // Prepend a '0' and a '.' and then as many more '0's as necessary.
+ val.append('0').append('.');
+ while (point < 0)
+ {
+ val.append('0');
+ point++;
+ }
+ // Append the unscaled value.
+ val.append(bigStr.substring(negative ? 1 : 0));
+ }
+ else
+ {
+ // No zeros need to be prepended so the String is simply the
+ // unscaled value with the decimal point inserted.
+ val.append(bigStr);
+ val.insert(point + (negative ? 1 : 0), '.');
+ }
+ }
+ else
+ {
+ // We must use scientific notation to represent this BigDecimal.
+ val.append(bigStr);
+ // If there is more than one digit in the unscaled value we put a
+ // decimal after the first digit.
+ if (bigStr.length() > 1)
+ val.insert(1, '.');
+ // And then append 'E' and the exponent (adjExp).
+ val.append('E');
+ if (adjExp >= 0)
+ val.append('+');
+ val.append(adjExp);
+ }
+ return val.toString();
+ }
- public String toString ()
+ /**
+ * Returns the String representation of this BigDecimal, using engineering
+ * notation if necessary. This is similar to toString() but when exponents
+ * are used the exponent is made to be a multiple of 3 such that the integer
+ * part is between 1 and 999.
+ *
+ * @return a String representation of this BigDecimal in engineering notation
+ * @since 1.5
+ */
+ public String toEngineeringString()
{
+ // bigStr is the String representation of the unscaled value. If
+ // scale is zero we simply return this.
String bigStr = intVal.toString();
- if (scale == 0)
+ if (scale == 0)
return bigStr;
+ // This is the adjusted exponent described above.
+ int adjExp = -scale + (numDigitsInLong(intVal.longValue()) - 1);
+ StringBuilder val = new StringBuilder();
+
+ if (scale >= 0 && adjExp >= -6)
+ {
+ // Convert to character form without scientific notation.
+ boolean negative = (bigStr.charAt(0) == '-');
+ int point = bigStr.length() - scale - (negative ? 1 : 0);
+ if (point <= 0)
+ {
+ // Zeros need to be prepended to the StringBuilder.
+ if (negative)
+ val.append('-');
+ // Prepend a '0' and a '.' and then as many more '0's as necessary.
+ val.append('0').append('.');
+ while (point < 0)
+ {
+ val.append('0');
+ point++;
+ }
+ // Append the unscaled value.
+ val.append(bigStr.substring(negative ? 1 : 0));
+ }
+ else
+ {
+ // No zeros need to be prepended so the String is simply the
+ // unscaled value with the decimal point inserted.
+ val.append(bigStr);
+ val.insert(point + (negative ? 1 : 0), '.');
+ }
+ }
+ else
+ {
+ // We must use scientific notation to represent this BigDecimal.
+ // The exponent must be a multiple of 3 and the integer part
+ // must be between 1 and 999.
+ val.append(bigStr);
+ int zeros = adjExp % 3;
+ int dot = 1;
+ if (adjExp > 0)
+ {
+ // If the exponent is positive we just move the decimal to the
+ // right and decrease the exponent until it is a multiple of 3.
+ dot += zeros;
+ adjExp -= zeros;
+ }
+ else
+ {
+ // If the exponent is negative then we move the dot to the right
+ // and decrease the exponent (increase its magnitude) until
+ // it is a multiple of 3. Note that this is not adjExp -= zeros
+ // because the mod operator doesn't give us the distance to the
+ // correct multiple of 3. (-5 mod 3) is -2 but the distance from
+ // -5 to the correct multiple of 3 (-6) is 1, not 2.
+ if (zeros == -2)
+ {
+ dot += 1;
+ adjExp -= 1;
+ }
+ else if (zeros == -1)
+ {
+ dot += 2;
+ adjExp -= 2;
+ }
+ }
+
+ // Either we have to append zeros because, for example, 1.1E+5 should
+ // be 110E+3, or we just have to put the decimal in the right place.
+ if (dot > val.length())
+ {
+ while (dot > val.length())
+ val.append('0');
+ }
+ else if (bigStr.length() > dot)
+ val.insert(dot, '.');
+
+ // And then append 'E' and the exponent (adjExp).
+ val.append('E');
+ if (adjExp >= 0)
+ val.append('+');
+ val.append(adjExp);
+ }
+ return val.toString();
+ }
+
+ /**
+ * Returns a String representation of this BigDecimal without using
+ * scientific notation. This is how toString() worked for releases 1.4
+ * and previous. Zeros may be added to the end of the String. For
+ * example, an unscaled value of 1234 and a scale of -3 would result in
+ * the String 1234000, but the toString() method would return
+ * 1.234E+6.
+ * @return a String representation of this BigDecimal
+ * @since 1.5
+ */
+ public String toPlainString()
+ {
+ // If the scale is zero we simply return the String representation of the
+ // unscaled value.
+ String bigStr = intVal.toString();
+ if (scale == 0)
+ return bigStr;
+
+ // Remember if we have to put a negative sign at the start.
boolean negative = (bigStr.charAt(0) == '-');
int point = bigStr.length() - scale - (negative ? 1 : 0);
- StringBuffer sb = new StringBuffer(bigStr.length() + 2 +
- (point <= 0 ? (-point + 1) : 0));
+ StringBuffer sb = new StringBuffer(bigStr.length() + 2
+ + (point <= 0 ? (-point + 1) : 0));
if (point <= 0)
{
+ // We have to prepend zeros and a decimal point.
if (negative)
sb.append('-');
sb.append('0').append('.');
@@ -482,24 +1283,95 @@ public class BigDecimal extends Number implements Comparable
}
sb.append(bigStr.substring(negative ? 1 : 0));
}
+ else if (point < bigStr.length())
+ {
+ // No zeros need to be prepended or appended, just put the decimal
+ // in the right place.
+ sb.append(bigStr);
+ sb.insert(point + (negative ? 1 : 0), '.');
+ }
else
{
- sb.append(bigStr);
- sb.insert(point + (negative ? 1 : 0), '.');
+ // We must append zeros instead of using scientific notation.
+ sb.append(bigStr);
+ for (int i = bigStr.length(); i < point; i++)
+ sb.append('0');
}
return sb.toString();
}
-
+
+ /**
+ * Converts this BigDecimal to a BigInteger. Any fractional part will
+ * be discarded.
+ * @return a BigDecimal whose value is equal to floor[this]
+ */
public BigInteger toBigInteger ()
{
- return scale == 0 ? intVal :
- intVal.divide (BigInteger.valueOf (10).pow (scale));
+ // If scale > 0 then we must divide, if scale > 0 then we must multiply,
+ // and if scale is zero then we just return intVal;
+ if (scale > 0)
+ return intVal.divide (BigInteger.TEN.pow (scale));
+ else if (scale < 0)
+ return intVal.multiply(BigInteger.TEN.pow(-scale));
+ return intVal;
+ }
+
+ /**
+ * Converts this BigDecimal into a BigInteger, throwing an
+ * ArithmeticException if the conversion is not exact.
+ * @return a BigInteger whose value is equal to the value of this BigDecimal
+ * @since 1.5
+ */
+ public BigInteger toBigIntegerExact()
+ {
+ if (scale > 0)
+ {
+ // If we have to divide, we must check if the result is exact.
+ BigInteger[] result =
+ intVal.divideAndRemainder(BigInteger.TEN.pow(scale));
+ if (result[1].equals(BigInteger.ZERO))
+ return result[0];
+ throw new ArithmeticException("No exact BigInteger representation");
+ }
+ else if (scale < 0)
+ // If we're multiplying instead, then we needn't check for exactness.
+ return intVal.multiply(BigInteger.TEN.pow(-scale));
+ // If the scale is zero we can simply return intVal.
+ return intVal;
}
public int intValue ()
{
return toBigInteger ().intValue ();
}
+
+ /**
+ * Returns a BigDecimal which is numerically equal to this BigDecimal but
+ * with no trailing zeros in the representation. For example, if this
+ * BigDecimal has [unscaledValue, scale] = [6313000, 4] this method returns
+ * a BigDecimal with [unscaledValue, scale] = [6313, 1]. As another
+ * example, [12400, -2] would become [124, -4].
+ * @return a numerically equal BigDecimal with no trailing zeros
+ */
+ public BigDecimal stripTrailingZeros()
+ {
+ String intValStr = intVal.toString();
+ int newScale = scale;
+ int pointer = intValStr.length() - 1;
+ // This loop adjusts pointer which will be used to give us the substring
+ // of intValStr to use in our new BigDecimal, and also accordingly
+ // adjusts the scale of our new BigDecimal.
+ while (intValStr.charAt(pointer) == '0')
+ {
+ pointer --;
+ newScale --;
+ }
+ // Create a new BigDecimal with the appropriate substring and then
+ // set its scale.
+ BigDecimal result = new BigDecimal(intValStr.substring(0, pointer + 1));
+ result.scale = newScale;
+ return result;
+ }
public long longValue ()
{
@@ -526,4 +1398,165 @@ public class BigDecimal extends Number implements Comparable
{
return divide (ONE, scale, roundingMode);
}
+
+ /**
+ * Returns a new BigDecimal constructed from the BigDecimal(String)
+ * constructor using the Double.toString(double) method to obtain
+ * the String.
+ * @param val the double value used in Double.toString(double)
+ * @return a BigDecimal representation of val
+ * @throws NumberFormatException if val is NaN or infinite
+ * @since 1.5
+ */
+ public static BigDecimal valueOf(double val)
+ {
+ if (Double.isInfinite(val) || Double.isNaN(val))
+ throw new NumberFormatException("argument cannot be NaN or infinite.");
+ return new BigDecimal(Double.toString(val));
+ }
+
+ /**
+ * Returns a BigDecimal whose numerical value is the numerical value
+ * of this BigDecimal multiplied by 10 to the power of <code>n</code>.
+ * @param n the power of ten
+ * @return the new BigDecimal
+ * @since 1.5
+ */
+ public BigDecimal scaleByPowerOfTen(int n)
+ {
+ BigDecimal result = new BigDecimal(intVal, scale - n);
+ result.precision = precision;
+ return result;
+ }
+
+ /**
+ * Returns a BigDecimal whose value is <code>this</code> to the power of
+ * <code>n</code>.
+ * @param n the power
+ * @return the new BigDecimal
+ * @since 1.5
+ */
+ public BigDecimal pow(int n)
+ {
+ if (n < 0 || n > 999999999)
+ throw new ArithmeticException("n must be between 0 and 999999999");
+ BigDecimal result = new BigDecimal(intVal.pow(n), scale * n);
+ return result;
+ }
+
+ /**
+ * Returns a BigDecimal whose value is determined by first calling pow(n)
+ * and then by rounding according to the MathContext mc.
+ * @param n the power
+ * @param mc the MathContext
+ * @return the new BigDecimal
+ * @throws ArithmeticException if n < 0 or n > 999999999 or if the result is
+ * inexact but the rounding is RoundingMode.UNNECESSARY
+ * @since 1.5
+ */
+ public BigDecimal pow(int n, MathContext mc)
+ {
+ // FIXME: The specs claim to use the X3.274-1996 algorithm. We
+ // currently do not.
+ return pow(n).round(mc);
+ }
+
+ /**
+ * Returns a BigDecimal whose value is the absolute value of this BigDecimal
+ * with rounding according to the given MathContext.
+ * @param mc the MathContext
+ * @return the new BigDecimal
+ */
+ public BigDecimal abs(MathContext mc)
+ {
+ BigDecimal result = abs();
+ result = result.round(mc);
+ return result;
+ }
+
+ /**
+ * Returns the size of a unit in the last place of this BigDecimal. This
+ * returns a BigDecimal with [unscaledValue, scale] = [1, this.scale()].
+ * @return the size of a unit in the last place of <code>this</code>.
+ * @since 1.5
+ */
+ public BigDecimal ulp()
+ {
+ return new BigDecimal(BigInteger.ONE, scale);
+ }
+
+ /**
+ * Converts this BigDecimal to a long value.
+ * @return the long value
+ * @throws ArithmeticException if rounding occurs or if overflow occurs
+ * @since 1.5
+ */
+ public long longValueExact()
+ {
+ // Set scale will throw an exception if rounding occurs.
+ BigDecimal temp = setScale(0, ROUND_UNNECESSARY);
+ BigInteger tempVal = temp.intVal;
+ // Check for overflow.
+ long result = intVal.longValue();
+ if (tempVal.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 1
+ || (result < 0 && signum() == 1) || (result > 0 && signum() == -1))
+ throw new ArithmeticException("this BigDecimal is too " +
+ "large to fit into the return type");
+
+ return intVal.longValue();
+ }
+
+ /**
+ * Converts this BigDecimal into an int by first calling longValueExact
+ * and then checking that the <code>long</code> returned from that
+ * method fits into an <code>int</code>.
+ * @return an int whose value is <code>this</code>
+ * @throws ArithmeticException if this BigDecimal has a fractional part
+ * or is too large to fit into an int.
+ * @since 1.5
+ */
+ public int intValueExact()
+ {
+ long temp = longValueExact();
+ int result = (int)temp;
+ if (result != temp)
+ throw new ArithmeticException ("this BigDecimal cannot fit into an int");
+ return result;
+ }
+
+ /**
+ * Converts this BigDecimal into a byte by first calling longValueExact
+ * and then checking that the <code>long</code> returned from that
+ * method fits into a <code>byte</code>.
+ * @return a byte whose value is <code>this</code>
+ * @throws ArithmeticException if this BigDecimal has a fractional part
+ * or is too large to fit into a byte.
+ * @since 1.5
+ */
+ public byte byteValueExact()
+ {
+ long temp = longValueExact();
+ byte result = (byte)temp;
+ if (result != temp)
+ throw new ArithmeticException ("this BigDecimal cannot fit into a byte");
+ return result;
+ }
+
+ /**
+ * Converts this BigDecimal into a short by first calling longValueExact
+ * and then checking that the <code>long</code> returned from that
+ * method fits into a <code>short</code>.
+ * @return a short whose value is <code>this</code>
+ * @throws ArithmeticException if this BigDecimal has a fractional part
+ * or is too large to fit into a short.
+ * @since 1.5
+ */
+ public short shortValueExact()
+ {
+ long temp = longValueExact();
+ short result = (short)temp;
+ if (result != temp)
+ throw new ArithmeticException ("this BigDecimal cannot fit into a short");
+ return result;
+ }
}
diff --git a/java/math/BigInteger.java b/java/math/BigInteger.java
index 86d6924af..b57cf607e 100644
--- a/java/math/BigInteger.java
+++ b/java/math/BigInteger.java
@@ -1168,7 +1168,7 @@ public class BigInteger extends Number implements Comparable
throw new ArithmeticException("non-positive modulo");
if (exponent.isNegative())
- return modInverse(m);
+ return modInverse(m).modPow(exponent.negate(), m);
if (exponent.isOne())
return mod(m);
diff --git a/java/math/MathContext.java b/java/math/MathContext.java
new file mode 100644
index 000000000..417d9c2e2
--- /dev/null
+++ b/java/math/MathContext.java
@@ -0,0 +1,144 @@
+/* MathContext.java --
+ 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;
+
+import java.io.Serializable;
+
+/**
+ * Immutable objects describing settings such as rounding mode and digit
+ * precision for numerical operations such as those in the BigDecimal class.
+ * @author Anthony Balkissoon abalkiss at redhat dot com
+ *
+ */
+public final class MathContext implements Serializable
+{
+
+ /**
+ * This is the serialVersionUID reported here:
+ * java.sun.com/j2se/1.5.0/docs/api/serialized-form.html#java.math.MathContext
+ */
+ private static final long serialVersionUID = 5579720004786848255L;
+
+ private int precision;
+
+ /**
+ * Constructs a new MathContext with the specified precision and with HALF_UP
+ * rounding.
+ * @param setPrecision the precision for the new MathContext
+ *
+ * @throws IllegalArgumentException if precision is < 0.
+ */
+ public MathContext(int setPrecision)
+ {
+ if (setPrecision < 0)
+ throw new IllegalArgumentException("Precision cannot be less than zero.");
+ precision = setPrecision;
+ }
+
+ /**
+ * Constructs a MathContext from a String that has the same form as one
+ * produced by the toString() method.
+ * @param val
+ *
+ * @throws IllegalArgumentException if the String is not in the correct
+ * format or if the precision specified is < 0.
+ */
+ public MathContext(String val)
+ {
+ try
+ {
+ int roundingModeIndex = val.indexOf("roundingMode", 10);
+ precision = Integer.parseInt(val.substring(10, roundingModeIndex - 1));
+ }
+ catch (NumberFormatException nfe)
+ {
+ throw new IllegalArgumentException("String not in correct format");
+ }
+ catch (IllegalArgumentException iae)
+ {
+ throw new IllegalArgumentException("String not in correct format");
+ }
+ if (precision < 0)
+ throw new IllegalArgumentException("Precision cannot be less than 0.");
+ }
+
+ /**
+ * Returns true if x is a MathContext and has the same precision setting
+ * and rounding mode as this MathContext.
+ *
+ * @return true if the above conditions hold
+ */
+ public boolean equals(Object x)
+ {
+ if (!(x instanceof MathContext))
+ return false;
+ MathContext mc = (MathContext)x;
+ return mc.precision == this.precision;
+ }
+
+ /**
+ * Returns the precision setting.
+ * @return the precision setting.
+ */
+ public int getPrecision()
+ {
+ return precision;
+ }
+
+ /**
+ * Returns "precision=p roundingMode=MODE" where p is an int giving the
+ * precision and MODE is UP, DOWN, HALF_UP, HALF_DOWN, HALF_EVEN, CEILING,
+ * FLOOR, or UNNECESSARY corresponding to rounding modes.
+ *
+ * @return a String describing this MathContext
+ */
+ public String toString()
+ {
+ return "precision="+precision;
+ }
+
+ /**
+ * Returns the hashcode for this MathContext.
+ * @return the hashcode for this MathContext.
+ */
+ public int hashCode()
+ {
+ return precision;
+ }
+}
diff --git a/java/net/InetSocketAddress.java b/java/net/InetSocketAddress.java
index 912545752..5267cc11a 100644
--- a/java/net/InetSocketAddress.java
+++ b/java/net/InetSocketAddress.java
@@ -86,7 +86,6 @@ public class InetSocketAddress extends SocketAddress
this.addr = addr;
this.port = port;
- this.hostname = addr.getHostName();
}
/**
@@ -186,7 +185,7 @@ public class InetSocketAddress extends SocketAddress
if (addr == null && sa.addr != null)
return false;
- else if (addr == null && sa.addr == null)
+ else if (addr == null && sa.addr == null) // we know hostname != null
return hostname.equals(sa.hostname) && sa.port == port;
else
return addr.equals(sa.addr) && sa.port == port;
@@ -213,6 +212,9 @@ public class InetSocketAddress extends SocketAddress
*/
public final String getHostName()
{
+ if (hostname == null) // we know addr != null
+ hostname = addr.getHostName();
+
return hostname;
}
@@ -249,10 +251,11 @@ public class InetSocketAddress extends SocketAddress
/**
* Returns the <code>InetSocketAddress</code> as string
*
- * @return A string represenation of this address.
+ * @return A string representation of this address.
*/
public String toString()
{
+ // Note: if addr is null, then hostname != null.
return (addr == null ? hostname : addr.toString()) + ":" + port;
}
}
diff --git a/java/net/URLClassLoader.java b/java/net/URLClassLoader.java
index 8d9e5ade7..403f7485c 100644
--- a/java/net/URLClassLoader.java
+++ b/java/net/URLClassLoader.java
@@ -39,15 +39,21 @@ exception statement from your version. */
package java.net;
-import gnu.java.net.IndexListParser;
+import gnu.java.net.loader.FileURLLoader;
+import gnu.java.net.loader.JarURLLoader;
+import gnu.java.net.loader.RemoteURLLoader;
+import gnu.java.net.loader.Resource;
+import gnu.java.net.loader.URLLoader;
+import gnu.java.net.loader.URLStreamHandlerCache;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.File;
-import java.io.FileInputStream;
import java.io.FilePermission;
import java.io.IOException;
import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.CodeSource;
@@ -57,13 +63,8 @@ import java.security.SecureClassLoader;
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.StringTokenizer;
import java.util.Vector;
import java.util.jar.Attributes;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
import java.util.jar.Manifest;
@@ -129,19 +130,17 @@ public class URLClassLoader extends SecureClassLoader
// Class Variables
/**
- * A global cache to store mappings between URLLoader and URL,
- * so we can avoid do all the homework each time the same URL
- * comes.
- * XXX - Keeps these loaders forever which prevents garbage collection.
+ * A cache to store mappings between handler factory and its
+ * private protocol handler cache (also a HashMap), so we can avoid
+ * creating handlers each time the same protocol comes.
*/
- private static HashMap urlloaders = new HashMap();
+ private static URLStreamHandlerCache factoryCache
+ = new URLStreamHandlerCache();
/**
- * A cache to store mappings between handler factory and its
- * private protocol handler cache (also a HashMap), so we can avoid
- * create handlers each time the same protocol comes.
+ * The prefix for URL loaders.
*/
- private static HashMap factoryCache = new HashMap(5);
+ private static final String URL_LOADER_PREFIX = "gnu.java.net.loader.Load_";
// Instance variables
@@ -169,494 +168,6 @@ public class URLClassLoader extends SecureClassLoader
// Helper classes
/**
- * A <code>URLLoader</code> contains all logic to load resources from a
- * given base <code>URL</code>.
- */
- abstract static class URLLoader
- {
- /**
- * Our classloader to get info from if needed.
- */
- final URLClassLoader classloader;
-
- /**
- * The base URL from which all resources are loaded.
- */
- final URL baseURL;
-
- /**
- * A <code>CodeSource</code> without any associated certificates.
- * It is common for classes to not have certificates associated
- * with them. If they come from the same <code>URLLoader</code>
- * then it is safe to share the associated <code>CodeSource</code>
- * between them since <code>CodeSource</code> is immutable.
- */
- final CodeSource noCertCodeSource;
-
- URLLoader(URLClassLoader classloader, URL baseURL)
- {
- this(classloader, baseURL, baseURL);
- }
-
- URLLoader(URLClassLoader classloader, URL baseURL, URL overrideURL)
- {
- this.classloader = classloader;
- this.baseURL = baseURL;
- this.noCertCodeSource = new CodeSource(overrideURL, null);
- }
-
- /**
- * Returns a <code>Resource</code> loaded by this
- * <code>URLLoader</code>, or <code>null</code> when no
- * <code>Resource</code> with the given name exists.
- */
- abstract Resource getResource(String s);
-
- /**
- * Returns the <code>Manifest</code> associated with the
- * <code>Resource</code>s loaded by this <code>URLLoader</code> or
- * <code>null</code> there is no such <code>Manifest</code>.
- */
- Manifest getManifest()
- {
- return null;
- }
-
- Vector getClassPath()
- {
- return null;
- }
- }
-
- /**
- * A <code>Resource</code> represents a resource in some
- * <code>URLLoader</code>. It also contains all information (e.g.,
- * <code>URL</code>, <code>CodeSource</code>, <code>Manifest</code> and
- * <code>InputStream</code>) that is necessary for loading resources
- * and creating classes from a <code>URL</code>.
- */
- abstract static class Resource
- {
- final URLLoader loader;
-
- Resource(URLLoader loader)
- {
- this.loader = loader;
- }
-
- /**
- * Returns the non-null <code>CodeSource</code> associated with
- * this resource.
- */
- CodeSource getCodeSource()
- {
- Certificate[] certs = getCertificates();
- if (certs == null)
- return loader.noCertCodeSource;
- else
- return new CodeSource(loader.baseURL, certs);
- }
-
- /**
- * Returns <code>Certificates</code> associated with this
- * resource, or null when there are none.
- */
- Certificate[] getCertificates()
- {
- return null;
- }
-
- /**
- * Return a <code>URL</code> that can be used to access this resource.
- */
- abstract URL getURL();
-
- /**
- * Returns the size of this <code>Resource</code> in bytes or
- * <code>-1</code> when unknown.
- */
- abstract int getLength();
-
- /**
- * Returns the non-null <code>InputStream</code> through which
- * this resource can be loaded.
- */
- abstract InputStream getInputStream() throws IOException;
- }
-
- /**
- * A <code>JarURLLoader</code> is a type of <code>URLLoader</code>
- * only loading from jar url.
- */
- static final class JarURLLoader extends URLLoader
- {
- final JarFile jarfile; // The jar file for this url
- final URL baseJarURL; // Base jar: url for all resources loaded from jar
-
- Vector classPath; // The "Class-Path" attribute of this Jar's manifest
-
- public JarURLLoader(URLClassLoader classloader, URL baseURL,
- URL absoluteUrl)
- {
- super(classloader, baseURL, absoluteUrl);
-
- // Cache url prefix for all resources in this jar url.
- String external = baseURL.toExternalForm();
- StringBuffer sb = new StringBuffer(external.length() + 6);
- sb.append("jar:");
- sb.append(external);
- sb.append("!/");
- String jarURL = sb.toString();
-
- this.classPath = null;
- URL baseJarURL = null;
- JarFile jarfile = null;
- try
- {
- baseJarURL =
- new URL(null, jarURL, classloader.getURLStreamHandler("jar"));
-
- jarfile =
- ((JarURLConnection) baseJarURL.openConnection()).getJarFile();
-
- Manifest manifest;
- Attributes attributes;
- String classPathString;
-
- this.classPath = new Vector();
-
- ArrayList indexListHeaders = new IndexListParser(jarfile, baseJarURL, baseURL).getHeaders();
- if (indexListHeaders.size() > 0)
- this.classPath.addAll(indexListHeaders);
- else if ((manifest = jarfile.getManifest()) != null
- && (attributes = manifest.getMainAttributes()) != null
- && ((classPathString
- = attributes.getValue(Attributes.Name.CLASS_PATH))
- != null))
- {
- StringTokenizer st = new StringTokenizer(classPathString, " ");
- while (st.hasMoreElements ())
- {
- String e = st.nextToken ();
- try
- {
- this.classPath.add(new URL(baseURL, e));
- }
- catch (java.net.MalformedURLException xx)
- {
- // Give up
- }
- }
- }
- }
- catch (IOException ioe)
- {
- /* ignored */
- }
-
- this.baseJarURL = baseJarURL;
- this.jarfile = jarfile;
- }
-
- /** get resource with the name "name" in the jar url */
- Resource getResource(String name)
- {
- if (jarfile == null)
- return null;
-
- if (name.startsWith("/"))
- name = name.substring(1);
-
- JarEntry je = jarfile.getJarEntry(name);
- if (je != null)
- return new JarURLResource(this, name, je);
- else
- return null;
- }
-
- Manifest getManifest()
- {
- try
- {
- return (jarfile == null) ? null : jarfile.getManifest();
- }
- catch (IOException ioe)
- {
- return null;
- }
- }
-
- Vector getClassPath()
- {
- return classPath;
- }
- }
-
- static final class JarURLResource extends Resource
- {
- private final JarEntry entry;
- private final String name;
-
- JarURLResource(JarURLLoader loader, String name, JarEntry entry)
- {
- super(loader);
- this.entry = entry;
- this.name = name;
- }
-
- InputStream getInputStream() throws IOException
- {
- return ((JarURLLoader) loader).jarfile.getInputStream(entry);
- }
-
- int getLength()
- {
- return (int) entry.getSize();
- }
-
- Certificate[] getCertificates()
- {
- // We have to get the entry from the jar file again, because the
- // certificates will not be available until the entire entry has
- // been read.
- return ((JarEntry) ((JarURLLoader) loader).jarfile.getEntry(name))
- .getCertificates();
- }
-
- URL getURL()
- {
- try
- {
- return new URL(((JarURLLoader) loader).baseJarURL, name,
- loader.classloader.getURLStreamHandler("jar"));
- }
- catch (MalformedURLException e)
- {
- InternalError ie = new InternalError();
- ie.initCause(e);
- throw ie;
- }
- }
- }
-
- /**
- * Loader for remote directories.
- */
- static final class RemoteURLLoader extends URLLoader
- {
- private final String protocol;
-
- RemoteURLLoader(URLClassLoader classloader, URL url)
- {
- super(classloader, url);
- protocol = url.getProtocol();
- }
-
- /**
- * Get a remote resource.
- * Returns null if no such resource exists.
- */
- Resource getResource(String name)
- {
- try
- {
- URL url =
- new URL(baseURL, name, classloader.getURLStreamHandler(protocol));
- URLConnection connection = url.openConnection();
-
- // Open the connection and check the stream
- // just to be sure it exists.
- int length = connection.getContentLength();
- InputStream stream = connection.getInputStream();
-
- // We can do some extra checking if it is a http request
- if (connection instanceof HttpURLConnection)
- {
- int response =
- ((HttpURLConnection) connection).getResponseCode();
- if (response / 100 != 2)
- return null;
- }
-
- if (stream != null)
- return new RemoteResource(this, name, url, stream, length);
- else
- return null;
- }
- catch (IOException ioe)
- {
- return null;
- }
- }
- }
-
- /**
- * A resource from some remote location.
- */
- static final class RemoteResource extends Resource
- {
- private final URL url;
- private final InputStream stream;
- private final int length;
-
- RemoteResource(RemoteURLLoader loader, String name, URL url,
- InputStream stream, int length)
- {
- super(loader);
- this.url = url;
- this.stream = stream;
- this.length = length;
- }
-
- InputStream getInputStream() throws IOException
- {
- return stream;
- }
-
- public int getLength()
- {
- return length;
- }
-
- public URL getURL()
- {
- return url;
- }
- }
-
- /**
- * A <code>FileURLLoader</code> is a type of <code>URLLoader</code>
- * only loading from file url.
- */
- static final class FileURLLoader extends URLLoader
- {
- File dir; //the file for this file url
-
- FileURLLoader(URLClassLoader classloader, URL url, URL absoluteUrl)
- {
- super(classloader, url, absoluteUrl);
- dir = new File(absoluteUrl.getFile());
- }
-
- /** get resource with the name "name" in the file url */
- Resource getResource(String name)
- {
- try
- {
- // Make sure that all components in name are valid by walking through
- // them
- File file = walkPathComponents(name);
-
- if (file == null)
- return null;
-
- return new FileResource(this, file);
- }
- catch (IOException e)
- {
- // Fall through...
- }
- return null;
- }
-
- /**
- * Walk all path tokens and check them for validity. At no moment, we are
- * allowed to reach a directory located "above" the root directory, stored
- * in "dir" property. We are also not allowed to enter a non existing
- * directory or a non directory component (plain file, symbolic link, ...).
- * An empty or null path is valid. Pathnames components are separated by
- * <code>File.separatorChar</code>
- *
- * @param resourceFileName the name to be checked for validity.
- * @return the canonical file pointed by the resourceFileName or null if the
- * walking failed
- * @throws IOException in case of issue when creating the canonical
- * resulting file
- * @see File#separatorChar
- */
- private File walkPathComponents(String resourceFileName) throws IOException
- {
- StringTokenizer stringTokenizer = new StringTokenizer(resourceFileName, File.separator);
- File currentFile = dir;
- int tokenCount = stringTokenizer.countTokens();
-
- for (int i = 0; i < tokenCount - 1; i++)
- {
- String currentToken = stringTokenizer.nextToken();
-
- // If we are at the root directory and trying to go up, the walking is
- // finished with an error
- if ("..".equals(currentToken) && currentFile.equals(dir))
- return null;
-
- currentFile = new File(currentFile, currentToken);
-
- // If the current file doesn't exist or is not a directory, the walking is
- // finished with an error
- if (! (currentFile.exists() && currentFile.isDirectory()))
- return null;
-
- }
-
- // Treat the last token differently, if it exists, because it does not need
- // to be a directory
- if (tokenCount > 0)
- {
- String currentToken = stringTokenizer.nextToken();
-
- if ("..".equals(currentToken) && currentFile.equals(dir))
- return null;
-
- currentFile = new File(currentFile, currentToken);
-
- // If the current file doesn't exist, the walking is
- // finished with an error
- if (! currentFile.exists())
- return null;
- }
-
- return currentFile.getCanonicalFile();
- }
- }
-
- static final class FileResource extends Resource
- {
- final File file;
-
- FileResource(FileURLLoader loader, File file)
- {
- super(loader);
- this.file = file;
- }
-
- InputStream getInputStream() throws IOException
- {
- return new FileInputStream(file);
- }
-
- public int getLength()
- {
- return (int) file.length();
- }
-
- public URL getURL()
- {
- try
- {
- return file.toURL();
- }
- catch (MalformedURLException e)
- {
- InternalError ie = new InternalError();
- ie.initCause(e);
- throw ie;
- }
- }
- }
-
- // Constructors
-
- /**
* Creates a URLClassLoader that gets classes from the supplied URLs.
* To determine if this classloader may be created the constructor of
* the super class (<code>SecureClassLoader</code>) is called first, which
@@ -753,14 +264,8 @@ public class URLClassLoader extends SecureClassLoader
this.factory = factory;
addURLs(urls);
- // If this factory is still not in factoryCache, add it,
- // since we only support three protocols so far, 5 is enough
- // for cache initial size
- synchronized (factoryCache)
- {
- if (factory != null && factoryCache.get(factory) == null)
- factoryCache.put(factory, new HashMap(5));
- }
+ // If this factory is still not in factoryCache, add it.
+ factoryCache.add(factory);
}
// Methods
@@ -785,72 +290,114 @@ public class URLClassLoader extends SecureClassLoader
// Reset the toString() value.
thisString = null;
- // Check global cache to see if there're already url loader
- // for this url.
- URLLoader loader = (URLLoader) urlloaders.get(newUrl);
- if (loader == null)
+ // Create a loader for this URL.
+ URLLoader loader = null;
+ String file = newUrl.getFile();
+ String protocol = newUrl.getProtocol();
+
+ // If we have a file: URL, we want to make it absolute
+ // here, before we decide whether it is really a jar.
+ URL absoluteURL;
+ if ("file".equals (protocol))
{
- String file = newUrl.getFile();
- String protocol = newUrl.getProtocol();
+ File dir = new File(file);
+ URL absUrl;
+ try
+ {
+ absoluteURL = dir.getCanonicalFile().toURL();
+ }
+ catch (IOException ignore)
+ {
+ try
+ {
+ absoluteURL = dir.getAbsoluteFile().toURL();
+ }
+ catch (MalformedURLException _)
+ {
+ // This really should not happen.
+ absoluteURL = newUrl;
+ }
+ }
+ }
+ else
+ {
+ // This doesn't hurt, and it simplifies the logic a
+ // little.
+ absoluteURL = newUrl;
+ }
- // If we have a file: URL, we want to make it absolute
- // here, before we decide whether it is really a jar.
- URL absoluteURL;
- if ("file".equals (protocol))
- {
- File dir = new File(file);
- URL absUrl;
- try
- {
- absoluteURL = dir.getCanonicalFile().toURL();
- }
- catch (IOException ignore)
- {
- try
- {
- absoluteURL = dir.getAbsoluteFile().toURL();
- }
- catch (MalformedURLException _)
- {
- // This really should not happen.
- absoluteURL = newUrl;
- }
- }
- }
- else
- {
- // This doesn't hurt, and it simplifies the logic a
- // little.
- absoluteURL = newUrl;
- }
+ // First see if we can find a handler with the correct name.
+ try
+ {
+ Class handler = Class.forName(URL_LOADER_PREFIX + protocol);
+ Class[] argTypes = new Class[] { URLClassLoader.class,
+ URLStreamHandlerCache.class,
+ URLStreamHandlerFactory.class,
+ URL.class,
+ URL.class };
+ Constructor k = handler.getDeclaredConstructor(argTypes);
+ loader
+ = (URLLoader) k.newInstance(new Object[] { this,
+ factoryCache,
+ factory,
+ newUrl,
+ absoluteURL });
+ }
+ catch (ClassNotFoundException ignore)
+ {
+ // Fall through.
+ }
+ catch (NoSuchMethodException nsme)
+ {
+ // Programming error in the class library.
+ InternalError vme
+ = new InternalError("couldn't find URLLoader constructor");
+ vme.initCause(nsme);
+ throw vme;
+ }
+ catch (InstantiationException inste)
+ {
+ // Programming error in the class library.
+ InternalError vme
+ = new InternalError("couldn't instantiate URLLoader");
+ vme.initCause(inste);
+ throw vme;
+ }
+ catch (InvocationTargetException ite)
+ {
+ // Programming error in the class library.
+ InternalError vme
+ = new InternalError("error instantiating URLLoader");
+ vme.initCause(ite);
+ throw vme;
+ }
+ catch (IllegalAccessException illae)
+ {
+ // Programming error in the class library.
+ InternalError vme
+ = new InternalError("invalid access to URLLoader");
+ vme.initCause(illae);
+ throw vme;
+ }
- // Check that it is not a directory
+ if (loader == null)
+ {
+ // If it is not a directory, use the jar loader.
if (! (file.endsWith("/") || file.endsWith(File.separator)))
- loader = new JarURLLoader(this, newUrl, absoluteURL);
+ loader = new JarURLLoader(this, factoryCache, factory,
+ newUrl, absoluteURL);
else if ("file".equals(protocol))
- loader = new FileURLLoader(this, newUrl, absoluteURL);
+ loader = new FileURLLoader(this, factoryCache, factory,
+ newUrl, absoluteURL);
else
- loader = new RemoteURLLoader(this, newUrl);
-
- // Cache it.
- urlloaders.put(newUrl, loader);
+ loader = new RemoteURLLoader(this, factoryCache, factory,
+ newUrl);
}
urlinfos.add(loader);
-
- Vector extraUrls = loader.getClassPath();
- if (extraUrls != null)
- {
- Iterator it = extraUrls.iterator();
- while (it.hasNext())
- {
- URL url = (URL)it.next();
- URLLoader extraLoader = (URLLoader) urlloaders.get(url);
- if (! urlinfos.contains (extraLoader))
- addURLImpl(url);
- }
- }
-
+ ArrayList extra = loader.getClassPath();
+ if (extra != null)
+ urlinfos.addAll(extra);
}
}
@@ -966,7 +513,20 @@ public class URLClassLoader extends SecureClassLoader
{
// Just try to find the resource by the (almost) same name
String resourceName = className.replace('.', '/') + ".class";
- Resource resource = findURLResource(resourceName);
+ int max = urlinfos.size();
+ Resource resource = null;
+ for (int i = 0; i < max && resource == null; i++)
+ {
+ URLLoader loader = (URLLoader)urlinfos.elementAt(i);
+ if (loader == null)
+ continue;
+
+ Class k = loader.getClass(className);
+ if (k != null)
+ return k;
+
+ resource = loader.getResource(resourceName);
+ }
if (resource == null)
throw new ClassNotFoundException(className + " not found in " + this);
@@ -1028,12 +588,13 @@ public class URLClassLoader extends SecureClassLoader
if (packageName != null && getPackage(packageName) == null)
{
// define the package
- Manifest manifest = resource.loader.getManifest();
+ Manifest manifest = resource.getLoader().getManifest();
if (manifest == null)
definePackage(packageName, null, null, null, null, null, null,
null);
else
- definePackage(packageName, manifest, resource.loader.baseURL);
+ definePackage(packageName, manifest,
+ resource.getLoader().getBaseURL());
}
// And finally construct the class!
@@ -1145,34 +706,6 @@ public class URLClassLoader extends SecureClassLoader
}
/**
- * If the URLStreamHandlerFactory has been set this return the appropriate
- * URLStreamHandler for the given protocol, if not set returns null.
- *
- * @param protocol the protocol for which we need a URLStreamHandler
- * @return the appropriate URLStreamHandler or null
- */
- URLStreamHandler getURLStreamHandler(String protocol)
- {
- if (factory == null)
- return null;
-
- URLStreamHandler handler;
- synchronized (factoryCache)
- {
- // Check if there're handler for the same protocol in cache.
- HashMap cache = (HashMap) factoryCache.get(factory);
- handler = (URLStreamHandler) cache.get(protocol);
- if (handler == null)
- {
- // Add it to cache.
- handler = factory.createURLStreamHandler(protocol);
- cache.put(protocol, handler);
- }
- }
- return handler;
- }
-
- /**
* Finds all the resources with a particular name from all the locations.
*
* @param resourceName the name of the resource to lookup
diff --git a/java/net/URLConnection.java b/java/net/URLConnection.java
index 1f78dd8e8..28142b10a 100644
--- a/java/net/URLConnection.java
+++ b/java/net/URLConnection.java
@@ -38,7 +38,6 @@ exception statement from your version. */
package java.net;
-import gnu.classpath.NotImplementedException;
import gnu.classpath.SystemProperties;
import java.io.IOException;
@@ -173,6 +172,11 @@ public abstract class URLConnection
private static SimpleDateFormat[] dateFormats;
private static boolean dateformats_initialized;
+
+ /**
+ * The timeout period.
+ */
+ private int timeout;
/* Cached ParsePosition, used when parsing dates. */
private ParsePosition position;
@@ -212,6 +216,38 @@ public abstract class URLConnection
}
/**
+ * Returns the connection timeout speed, in milliseconds, or zero if the timeout
+ * is infinite or not set.
+ *
+ * @return The timeout.
+ *
+ * @since 1.5
+ */
+ public int getConnectTimeout()
+ {
+ return timeout;
+ }
+
+ /**
+ * Set the connection timeout speed, in milliseconds, or zero if the timeout
+ * is to be considered infinite. Note that in certain socket
+ * implementations/platforms this method may not have any effect.
+ *
+ * Throws an <code>IllegalArgumentException</code> if timeout < 0.
+ *
+ * @param timeout - The timeout, in milliseconds.
+ *
+ * @since 1.5
+ */
+ public void setConnectTimeout(int timeout)
+ throws IllegalArgumentException
+ {
+ if( timeout < 0 )
+ throw new IllegalArgumentException("Timeout must be 0 or positive.");
+ this.timeout = timeout;
+ }
+
+ /**
* Returns the value of the content-length header field or -1 if the value
* is not known or not present.
*
@@ -934,11 +970,12 @@ public abstract class URLConnection
* @exception IOException If an error occurs
*/
public static String guessContentTypeFromStream(InputStream is)
- throws IOException, NotImplementedException
+ throws IOException
{
- // See /etc/gnome-vfs-mime-magic or /etc/mime-magic for a reasonable
- // idea of how to handle this.
- return "application/octet-stream";
+ String result = VMURLConnection.guessContentTypeFromStream(is);
+ if (result == null)
+ return "application/octet-stream";
+ return result;
}
/**
diff --git a/java/nio/ByteBufferImpl.java b/java/nio/ByteBufferImpl.java
index cbe627b06..aa51a65bd 100644
--- a/java/nio/ByteBufferImpl.java
+++ b/java/nio/ByteBufferImpl.java
@@ -115,12 +115,10 @@ final class ByteBufferImpl extends ByteBuffer
checkIfReadOnly();
mark = -1;
int pos = position();
- if (pos > 0)
- {
- int count = remaining();
- shiftDown(0, pos, count);
- position(count);
- }
+ int n = limit() - pos;
+ if (n > 0)
+ shiftDown(0, pos, n);
+ position(n);
limit(capacity());
return this;
}
diff --git a/java/nio/CharBuffer.java b/java/nio/CharBuffer.java
index 6551555e2..356a920ee 100644
--- a/java/nio/CharBuffer.java
+++ b/java/nio/CharBuffer.java
@@ -107,14 +107,12 @@ public abstract class CharBuffer extends Buffer
{
// FIXME: implement better handling of java.lang.String.
// Probably share data with String via reflection.
-
- if ((start < 0)
- || (start > seq.length())
- || (end < start)
- || (end > (seq.length() - start)))
- throw new IndexOutOfBoundsException();
-
+
int len = end - start;
+
+ if( len < 0 )
+ throw new IndexOutOfBoundsException();
+
char[] buffer = new char[len];
for (int i = 0; i < len; i++)
diff --git a/java/nio/channels/FileChannel.java b/java/nio/channels/FileChannel.java
index 0eefffbe9..3aa199909 100644
--- a/java/nio/channels/FileChannel.java
+++ b/java/nio/channels/FileChannel.java
@@ -114,12 +114,7 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
*/
public final long write(ByteBuffer[] srcs) throws IOException
{
- long result = 0;
-
- for (int i = 0; i < srcs.length; i++)
- result += write(srcs[i]);
-
- return result;
+ return write(srcs, 0, srcs.length);
}
/**
@@ -169,12 +164,7 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
*/
public final long read(ByteBuffer[] dsts) throws IOException
{
- long result = 0;
-
- for (int i = 0; i < dsts.length; i++)
- read(dsts[i]);
-
- return result;
+ return read(dsts, 0, dsts.length);
}
/**
diff --git a/java/text/NumberFormat.java b/java/text/NumberFormat.java
index 5fede9ee3..a42e9b3d9 100644
--- a/java/text/NumberFormat.java
+++ b/java/text/NumberFormat.java
@@ -481,7 +481,7 @@ public abstract class NumberFormat extends Format implements Cloneable
*/
public static NumberFormat getIntegerInstance(Locale locale)
{
- NumberFormat format = computeInstance (locale, "numberFormat", "#,##0");
+ NumberFormat format = computeInstance (locale, "integerFormat", "#,##0");
format.setMaximumFractionDigits(0);
format.setParseIntegerOnly (true);
return format;
diff --git a/java/util/Collections.java b/java/util/Collections.java
index 101a61838..8849face3 100644
--- a/java/util/Collections.java
+++ b/java/util/Collections.java
@@ -4822,9 +4822,9 @@ public class Collections
private static final class UnmodifiableMapEntry
implements Map.Entry
{
- private final Entry e;
+ private final Map.Entry e;
- private UnmodifiableMapEntry(Entry e)
+ private UnmodifiableMapEntry(Map.Entry e)
{
super();
this.e = e;
@@ -4944,7 +4944,8 @@ public class Collections
result = new UnmodifiableMapEntry[mapEntryResult.length];
for (int i = 0; i < mapEntryResult.length; i++)
{
- result[i] = new UnmodifiableMapEntry((Entry) mapEntryResult[i]);
+ Map.Entry r = (Map.Entry) mapEntryResult[i];
+ result[i] = new UnmodifiableMapEntry(r);
}
}
return result;
@@ -4960,7 +4961,7 @@ public class Collections
{
for (int i = 0; i < array.length; i++)
{
- array[i] = new UnmodifiableMapEntry((Entry) array[i]);
+ array[i] = new UnmodifiableMapEntry((Map.Entry) array[i]);
}
}
return array;
diff --git a/native/jni/gtk-peer/gtkcairopeer.h b/java/util/DuplicateFormatFlagsException.java
index dee843c8a..c180605cd 100644
--- a/native/jni/gtk-peer/gtkcairopeer.h
+++ b/java/util/DuplicateFormatFlagsException.java
@@ -1,8 +1,5 @@
-#ifndef __GTKCAIROPEER_H__
-#define __GTKCAIROPEER_H__
-
-/* gtkcairopeer.h -- Some global variables and #defines
- Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+/* DuplicateFormatFlagsException.java
+ Copyright (C) 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,56 +35,54 @@ 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. */
-#include "gtkpeer.h"
-#include <cairo.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-
-/*
- A graphics2d struct is both simpler and uglier than a graphics
- struct.
-
- Most of the graphics2d drawing state is held in the referenced cairo_t
- and corresponding cairo_surface_t, so we can ignore it.
- In addition to the cairo_t, we need to hold an extra reference to the
- underlying GdkDrawable so its refcount matches the lifecycle of the java
- Graphics object which is peering with us; also a reference to a byte
- buffer and cairo_surface_t which contain the pattern you're drawing from
- (if it exists).
+package java.util;
- Finally, it is possible that we are using a non-RENDER capable X server,
- therefore we will be drawing to an cairo_surface_t which is actually a
- pixbuf. When this is the case, the pointer to a GdkPixbuf will be
- non-NULL and any drawing operation needs to be bracketed by pixbuf
- load/save operations. If the GdkPixbuf pointer is NULL, we will treat
- the cairo_surface_t as RENDER-capable.
+/**
+ * Thrown when the flags supplied to the {@link Formatter#format()}
+ * method of a {@link Formatter} contain duplicates.
+ *
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
*/
-
-struct graphics2d
+public class DuplicateFormatFlagsException
+ extends IllegalFormatException
{
- cairo_t *cr;
- cairo_surface_t *surface;
- GdkDrawable *drawable;
- GdkWindow *win;
- GdkPixbuf *drawbuf;
- char *pattern_pixels;
- cairo_surface_t *pattern_surface;
- cairo_pattern_t *pattern;
- gboolean debug;
- enum
- {
- MODE_DRAWABLE_WITH_RENDER,
- MODE_DRAWABLE_NO_RENDER,
- MODE_JAVA_ARRAY
- }
- mode;
+ private static final long serialVersionUID = 18890531L;
+
+ /**
+ * The flags which contain a duplicate.
+ *
+ * @serial the flags containing a duplicate.
+ */
+ // Note: name fixed by serialization.
+ private String flags;
- /* Support for MODE_JAVA_ARRAY */
- jintArray jarray;
- jint width, height;
- jint *javabuf;
- jint *javabuf_copy;
- jboolean isCopy;
-};
+ /**
+ * Constructs a new <code>DuplicateFormatFlagsException</code>
+ * which specifies that the supplied set of flags contains a
+ * duplicate.
+ *
+ * @param flags the flags containing a duplicate.
+ * @throws NullPointerException if <code>flags</code> is null.
+ */
+ public DuplicateFormatFlagsException(String flags)
+ {
+ super("Duplicate flag passed in " + flags);
+ if (flags == null)
+ throw new
+ NullPointerException("Null flags value passed to constructor.");
+ this.flags = flags;
+ }
-#endif /* __GTKCAIROPEER_H */
+ /**
+ * Returns the flags which contain a duplicate.
+ *
+ * @return the flags.
+ */
+ public String getFlags()
+ {
+ return flags;
+ }
+}
diff --git a/java/util/FormatFlagsConversionMismatchException.java b/java/util/FormatFlagsConversionMismatchException.java
new file mode 100644
index 000000000..ec3177305
--- /dev/null
+++ b/java/util/FormatFlagsConversionMismatchException.java
@@ -0,0 +1,111 @@
+/* FormatFlagsConversionMismatchException.java
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.util;
+
+/**
+ * Thrown when the flags supplied to the {@link Formatter#format()}
+ * method of a {@link Formatter} contains a flag that does not match
+ * the conversion character specified for it.
+ *
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+public class FormatFlagsConversionMismatchException
+ extends IllegalFormatException
+{
+ private static final long serialVersionUID = 19120414L;
+
+ /**
+ * The mismatching flag.
+ *
+ * @serial the mismatching flag.
+ */
+ // Note: name fixed by serialization.
+ private String f;
+
+ /**
+ * The conversion character which doesn't match the
+ * appropriate flag.
+ *
+ * @serial the conversion character which doesn't match its flag.
+ */
+ // Note: name fixed by serialization.
+ private char c;
+
+ /**
+ * Constructs a new <code>FormatFlagsConversionMismatchException</code>
+ * which specifies that the flag, <code>f</code>, does
+ * not match its appropriate conversion character, <code>c</code>.
+ *
+ * @param f the mismatching flag.
+ * @param c the conversion character which doesn't match its flag.
+ * @throws NullPointerException if <code>f</code> is null.
+ */
+ public FormatFlagsConversionMismatchException(String f, char c)
+ {
+ super("Invalid flag " + f + " for conversion " + c);
+ if (f == null)
+ throw new
+ NullPointerException("Null flag value passed to constructor.");
+ this.f = f;
+ this.c = c;
+ }
+
+ /**
+ * Returns the conversion character which doesn't
+ * match the flag.
+ *
+ * @return the conversion character.
+ */
+ public char getConversion()
+ {
+ return c;
+ }
+
+ /**
+ * Returns the mismatching flag.
+ *
+ * @return the mismatching flag.
+ */
+ public String getFlags()
+ {
+ return f;
+ }
+}
diff --git a/java/util/Formattable.java b/java/util/Formattable.java
new file mode 100644
index 000000000..27e26a701
--- /dev/null
+++ b/java/util/Formattable.java
@@ -0,0 +1,92 @@
+/* Formattable.java -- Objects which can be passed to a Formatter
+ 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.util;
+
+/**
+ * <p>
+ * The <code>Formattable</code> interface is used to provide customised
+ * formatting to arbitrary objects via the {@link Formatter}. The
+ * {@link #formatTo} method is called for <code>Formattable</code>
+ * objects used with the 's' conversion operator, allowing the object
+ * to provide its own formatting of its internal data.
+ * </p>
+ * <p>
+ * Thread safety is left up to the implementing class. Thus,
+ * {@link Formattable} objects are not guaranteed to be thread-safe,
+ * and users should make their own provisions for multiple thread access.
+ * </p>
+ *
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+public interface Formattable
+{
+
+ /**
+ * Formats the object using the supplied formatter to the specification
+ * provided by the given flags, width and precision.
+ *
+ * @param formatter the formatter to use for formatting the object.
+ * The formatter gives access to the output stream
+ * and locale via {@link Formatter#out()} and
+ * {@link Formatter#locale()} respectively.
+ * @param flags a bit mask constructed from the flags in the
+ * {@link FormattableFlags} class. When no flags
+ * are set, the implementing class should use its
+ * defaults.
+ * @param width the minimum number of characters to include.
+ * A value of -1 indicates no minimum. The remaining
+ * space is padded with ' ' either on the left
+ * (the default) or right (if left justification is
+ * specified by the flags).
+ * @param precision the maximum number of characters to include.
+ * A value of -1 indicates no maximum. This value
+ * is applied prior to the minimum (the width). Thus,
+ * a value may meet the minimum width initially, but
+ * not when the width value is applied, due to
+ * characters being removed by the precision value.
+ * @throws IllegalFormatException if there is a problem with
+ * the syntax of the format
+ * specification or a mismatch
+ * between it and the arguments.
+ */
+ public void formatTo(Formatter formatter, int flags, int width,
+ int precision);
+}
diff --git a/java/util/FormattableFlags.java b/java/util/FormattableFlags.java
new file mode 100644
index 000000000..648b3c038
--- /dev/null
+++ b/java/util/FormattableFlags.java
@@ -0,0 +1,123 @@
+/* FormattableFlags.java --
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.util;
+
+/**
+ * This class contains a set of flags used
+ * by the {@link Formattable#formatTo()} method.
+ * They are used to modify the output of the
+ * {@link Formattable}. The interpretation and
+ * validation of the flags is left to the
+ * particular {@link Formattable}.
+ *
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+public class FormattableFlags
+{
+
+ /**
+ * Requires the output to be left-justified. Any spaces
+ * required to meet the specified width will be added to
+ * the right of the output. The default output is
+ * right-justified, where spaces are added to the left.
+ * The output is as for the format specifier
+ * '-' ('\u002d').
+ */
+ public static final int LEFT_JUSTIFY = 1;
+
+ /**
+ * Requires the output to be in uppercase. The output
+ * should be the same as the result from calling
+ * {@link String#toUpperCase(java.util.Locale)} with
+ * the formatting locale. The output is as for the
+ * format specifier '^' ('\u005e').
+ */
+ public static final int UPPERCASE = 2;
+
+ /**
+ * Requires the use of an alternate form, as specified
+ * in the documentation of {@link Formattable}.
+ * The output is as for the format specifier
+ * '#' ('\u0023').
+ */
+ public static final int ALTERNATE = 4;
+
+ // Used internally by Formatter.
+ // Changes here must be reflected in the FLAGS string there.
+
+ /**
+ * Requires the output to always include a '+' sign.
+ * The output is as for the format specifier '+'.
+ */
+ static final int PLUS = 8;
+
+ /**
+ * Requires the output to include a leading space on
+ * positive value. The output is as for the format
+ * specifier ' '.
+ */
+ static final int SPACE = 16;
+
+ /**
+ * Requires the output to be zero-padded. The output
+ * is as for the format specifier '0'.
+ */
+ static final int ZERO = 32;
+
+ /**
+ * Requires the output to include locale-specific
+ * grouping operators. The output is as for the
+ * format specifier ','.
+ */
+ static final int COMMA = 64;
+
+ /**
+ * Requires the output to include negative numbers
+ * enclosed in parentheses. The output is as for
+ * the format specifier '('.
+ */
+ static final int PAREN = 128;
+
+ // Not instantiable.
+ private FormattableFlags()
+ {
+ }
+}
diff --git a/java/util/Formatter.java b/java/util/Formatter.java
new file mode 100644
index 000000000..01d546315
--- /dev/null
+++ b/java/util/Formatter.java
@@ -0,0 +1,1294 @@
+/* Formatter.java -- printf-style formatting
+ 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.util;
+
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.Flushable;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.text.DateFormatSymbols;
+import java.text.DecimalFormatSymbols;
+
+import gnu.classpath.SystemProperties;
+
+/**
+ * <p>
+ * A Java formatter for <code>printf</code>-style format strings,
+ * as seen in the C programming language. This differs from the
+ * C interpretation of such strings by performing much stricter
+ * checking of format specifications and their corresponding
+ * arguments. While unknown conversions will be ignored in C,
+ * and invalid conversions will only produce compiler warnings,
+ * the Java version utilises a full range of run-time exceptions to
+ * handle these cases. The Java version is also more customisable
+ * by virtue of the provision of the {@link Formattable} interface,
+ * which allows an arbitrary class to be formatted by the formatter.
+ * </p>
+ * <p>
+ * The formatter is accessible by more convienient static methods.
+ * For example, streams now have appropriate format methods
+ * (the equivalent of <code>fprintf</code>) as do <code>String</code>
+ * objects (the equivalent of <code>sprintf</code>).
+ * </p>
+ * <p>
+ * <strong>Note</strong>: the formatter is not thread-safe. For
+ * multi-threaded access, external synchronization should be provided.
+ * </p>
+ *
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+public final class Formatter
+ implements Closeable, Flushable
+{
+
+ /**
+ * The output of the formatter.
+ */
+ private StringBuilder out;
+
+ /**
+ * The locale used by the formatter.
+ */
+ private Locale locale;
+
+ /**
+ * Whether or not the formatter is closed.
+ */
+ private boolean closed;
+
+ /**
+ * The last I/O exception thrown by the output stream.
+ */
+ private IOException ioException;
+
+ // Some state used when actually formatting.
+ /**
+ * The format string.
+ */
+ private String format;
+
+ /**
+ * The current index into the string.
+ */
+ private int index;
+
+ /**
+ * The length of the format string.
+ */
+ private int length;
+
+ /**
+ * The formatting locale.
+ */
+ private Locale fmtLocale;
+
+ // Note that we include '-' twice. The flags are ordered to
+ // correspond to the values in FormattableFlags, and there is no
+ // flag (in the sense of this field used when parsing) for
+ // UPPERCASE; the second '-' serves as a placeholder.
+ /**
+ * A string used to index into the formattable flags.
+ */
+ private static final String FLAGS = "--#+ 0,(";
+
+ /**
+ * The system line separator.
+ */
+ private static final String lineSeparator
+ = SystemProperties.getProperty("line.separator");
+
+ /**
+ * Constructs a new <code>Formatter</code> using the default
+ * locale and a {@link StringBuilder} as the output stream.
+ */
+ public Formatter()
+ {
+ this(null, Locale.getDefault());
+ }
+
+ /**
+ * Constructs a new <code>Formatter</code> using the specified
+ * locale and a {@link StringBuilder} as the output stream.
+ * If the locale is <code>null</code>, then no localization
+ * is applied.
+ *
+ * @param loc the locale to use.
+ */
+ public Formatter(Locale loc)
+ {
+ this(null, loc);
+ }
+
+ /**
+ * Constructs a new <code>Formatter</code> using the default
+ * locale and the specified output stream.
+ *
+ * @param app the output stream to use.
+ */
+ public Formatter(StringBuilder app)
+ {
+ this(app, Locale.getDefault());
+ }
+
+ /**
+ * Constructs a new <code>Formatter</code> using the specified
+ * locale and the specified output stream. If the locale is
+ * <code>null</code>, then no localization is applied.
+ *
+ * @param app the output stream to use.
+ * @param loc the locale to use.
+ */
+ public Formatter(StringBuilder app, Locale loc)
+ {
+ this.out = app == null ? new StringBuilder() : app;
+ this.locale = loc;
+ }
+
+ /**
+ * Closes the formatter, so as to release used resources.
+ * If the underlying output stream supports the {@link Closeable}
+ * interface, then this is also closed. Attempts to use
+ * a formatter instance, via any method other than
+ * {@link #ioException()}, after closure results in a
+ * {@link FormatterClosedException}.
+ */
+ public void close()
+ {
+ if (closed)
+ return;
+ closed = true;
+ }
+
+ /**
+ * Flushes the formatter, writing any cached data to the output
+ * stream. If the underlying output stream supports the
+ * {@link Flushable} interface, it is also flushed.
+ *
+ * @throws FormatterClosedException if the formatter is closed.
+ */
+ public void flush()
+ {
+ if (closed)
+ throw new FormatterClosedException();
+ }
+
+ /**
+ * Return the name corresponding to a flag.
+ *
+ * @param flags the flag to return the name of.
+ * @return the name of the flag.
+ */
+ private String getName(int flags)
+ {
+ // FIXME: do we want all the flags in here?
+ // Or should we redo how this is reported?
+ int bit = Integer.numberOfTrailingZeros(flags);
+ return FLAGS.substring(bit, bit + 1);
+ }
+
+ /**
+ * Verify the flags passed to a conversion.
+ *
+ * @param flags the flags to verify.
+ * @param allowed the allowed flags mask.
+ * @param conversion the conversion character.
+ */
+ private void checkFlags(int flags, int allowed, char conversion)
+ {
+ flags &= ~allowed;
+ if (flags != 0)
+ throw new FormatFlagsConversionMismatchException(getName(flags),
+ conversion);
+ }
+
+ /**
+ * Throw an exception if a precision was specified.
+ *
+ * @param precision the precision value (-1 indicates not specified).
+ */
+ private void noPrecision(int precision)
+ {
+ if (precision != -1)
+ throw new IllegalFormatPrecisionException(precision);
+ }
+
+ /**
+ * Apply the numeric localization algorithm to a StringBuilder.
+ *
+ * @param builder the builder to apply to.
+ * @param flags the formatting flags to use.
+ * @param width the width of the numeric value.
+ * @param isNegative true if the value is negative.
+ */
+ private void applyLocalization(StringBuilder builder, int flags, int width,
+ boolean isNegative)
+ {
+ DecimalFormatSymbols dfsyms;
+ if (fmtLocale == null)
+ dfsyms = new DecimalFormatSymbols();
+ else
+ dfsyms = new DecimalFormatSymbols(fmtLocale);
+
+ // First replace each digit.
+ char zeroDigit = dfsyms.getZeroDigit();
+ int decimalOffset = -1;
+ for (int i = builder.length() - 1; i >= 0; --i)
+ {
+ char c = builder.charAt(i);
+ if (c >= '0' && c <= '9')
+ builder.setCharAt(i, (char) (c - '0' + zeroDigit));
+ else if (c == '.')
+ {
+ assert decimalOffset == -1;
+ decimalOffset = i;
+ }
+ }
+
+ // Localize the decimal separator.
+ if (decimalOffset != -1)
+ {
+ builder.deleteCharAt(decimalOffset);
+ builder.insert(decimalOffset, dfsyms.getDecimalSeparator());
+ }
+
+ // Insert the grouping separators.
+ if ((flags & FormattableFlags.COMMA) != 0)
+ {
+ char groupSeparator = dfsyms.getGroupingSeparator();
+ int groupSize = 3; // FIXME
+ int offset = (decimalOffset == -1) ? builder.length() : decimalOffset;
+ // We use '>' because we don't want to insert a separator
+ // before the first digit.
+ for (int i = offset - groupSize; i > 0; i -= groupSize)
+ builder.insert(i, groupSeparator);
+ }
+
+ if ((flags & FormattableFlags.ZERO) != 0)
+ {
+ // Zero fill. Note that according to the algorithm we do not
+ // insert grouping separators here.
+ for (int i = width - builder.length(); i > 0; --i)
+ builder.insert(0, zeroDigit);
+ }
+
+ if (isNegative)
+ {
+ if ((flags & FormattableFlags.PAREN) != 0)
+ {
+ builder.insert(0, '(');
+ builder.append(')');
+ }
+ else
+ builder.insert(0, '-');
+ }
+ else if ((flags & FormattableFlags.PLUS) != 0)
+ builder.insert(0, '+');
+ else if ((flags & FormattableFlags.SPACE) != 0)
+ builder.insert(0, ' ');
+ }
+
+ /**
+ * A helper method that handles emitting a String after applying
+ * precision, width, justification, and upper case flags.
+ *
+ * @param arg the string to emit.
+ * @param flags the formatting flags to use.
+ * @param width the width to use.
+ * @param precision the precision to use.
+ * @throws IOException if the output stream throws an I/O error.
+ */
+ private void genericFormat(String arg, int flags, int width, int precision)
+ throws IOException
+ {
+ if ((flags & FormattableFlags.UPPERCASE) != 0)
+ {
+ if (fmtLocale == null)
+ arg = arg.toUpperCase();
+ else
+ arg = arg.toUpperCase(fmtLocale);
+ }
+
+ if (precision >= 0 && arg.length() > precision)
+ arg = arg.substring(0, precision);
+
+ boolean leftJustify = (flags & FormattableFlags.LEFT_JUSTIFY) != 0;
+ if (leftJustify && width == -1)
+ throw new MissingFormatWidthException("fixme");
+ if (! leftJustify && arg.length() < width)
+ {
+ for (int i = width - arg.length(); i > 0; --i)
+ out.append(' ');
+ }
+ out.append(arg);
+ if (leftJustify && arg.length() < width)
+ {
+ for (int i = width - arg.length(); i > 0; --i)
+ out.append(' ');
+ }
+ }
+
+ /**
+ * Emit a boolean.
+ *
+ * @param arg the boolean to emit.
+ * @param flags the formatting flags to use.
+ * @param width the width to use.
+ * @param precision the precision to use.
+ * @param conversion the conversion character.
+ * @throws IOException if the output stream throws an I/O error.
+ */
+ private void booleanFormat(Object arg, int flags, int width, int precision,
+ char conversion)
+ throws IOException
+ {
+ checkFlags(flags,
+ FormattableFlags.LEFT_JUSTIFY | FormattableFlags.UPPERCASE,
+ conversion);
+ String result;
+ if (arg instanceof Boolean)
+ result = String.valueOf((Boolean) arg);
+ else
+ result = arg == null ? "false" : "true";
+ genericFormat(result, flags, width, precision);
+ }
+
+ /**
+ * Emit a hash code.
+ *
+ * @param arg the hash code to emit.
+ * @param flags the formatting flags to use.
+ * @param width the width to use.
+ * @param precision the precision to use.
+ * @param conversion the conversion character.
+ * @throws IOException if the output stream throws an I/O error.
+ */
+ private void hashCodeFormat(Object arg, int flags, int width, int precision,
+ char conversion)
+ throws IOException
+ {
+ checkFlags(flags,
+ FormattableFlags.LEFT_JUSTIFY | FormattableFlags.UPPERCASE,
+ conversion);
+ genericFormat(arg == null ? "null" : Integer.toHexString(arg.hashCode()),
+ flags, width, precision);
+ }
+
+ /**
+ * Emit a String or Formattable conversion.
+ *
+ * @param arg the String or Formattable to emit.
+ * @param flags the formatting flags to use.
+ * @param width the width to use.
+ * @param precision the precision to use.
+ * @param conversion the conversion character.
+ * @throws IOException if the output stream throws an I/O error.
+ */
+ private void stringFormat(Object arg, int flags, int width, int precision,
+ char conversion)
+ throws IOException
+ {
+ if (arg instanceof Formattable)
+ {
+ checkFlags(flags,
+ (FormattableFlags.LEFT_JUSTIFY
+ | FormattableFlags.UPPERCASE
+ | FormattableFlags.ALTERNATE),
+ conversion);
+ Formattable fmt = (Formattable) arg;
+ fmt.formatTo(this, flags, width, precision);
+ }
+ else
+ {
+ checkFlags(flags,
+ FormattableFlags.LEFT_JUSTIFY | FormattableFlags.UPPERCASE,
+ conversion);
+ genericFormat(arg == null ? "null" : arg.toString(), flags, width,
+ precision);
+ }
+ }
+
+ /**
+ * Emit a character.
+ *
+ * @param arg the character to emit.
+ * @param flags the formatting flags to use.
+ * @param width the width to use.
+ * @param precision the precision to use.
+ * @param conversion the conversion character.
+ * @throws IOException if the output stream throws an I/O error.
+ */
+ private void characterFormat(Object arg, int flags, int width, int precision,
+ char conversion)
+ throws IOException
+ {
+ checkFlags(flags,
+ FormattableFlags.LEFT_JUSTIFY | FormattableFlags.UPPERCASE,
+ conversion);
+ noPrecision(precision);
+
+ int theChar;
+ if (arg instanceof Character)
+ theChar = ((Character) arg).charValue();
+ else if (arg instanceof Byte)
+ theChar = (char) (((Byte) arg).byteValue ());
+ else if (arg instanceof Short)
+ theChar = (char) (((Short) arg).shortValue ());
+ else if (arg instanceof Integer)
+ {
+ theChar = ((Integer) arg).intValue();
+ if (! Character.isValidCodePoint(theChar))
+ throw new IllegalFormatCodePointException(theChar);
+ }
+ else
+ throw new IllegalFormatConversionException(conversion, arg.getClass());
+ String result = new String(Character.toChars(theChar));
+ genericFormat(result, flags, width, precision);
+ }
+
+ /**
+ * Emit a '%'.
+ *
+ * @param flags the formatting flags to use.
+ * @param width the width to use.
+ * @param precision the precision to use.
+ * @throws IOException if the output stream throws an I/O error.
+ */
+ private void percentFormat(int flags, int width, int precision)
+ throws IOException
+ {
+ checkFlags(flags, FormattableFlags.LEFT_JUSTIFY, '%');
+ noPrecision(precision);
+ genericFormat("%", flags, width, precision);
+ }
+
+ /**
+ * Emit a newline.
+ *
+ * @param flags the formatting flags to use.
+ * @param width the width to use.
+ * @param precision the precision to use.
+ * @throws IOException if the output stream throws an I/O error.
+ */
+ private void newLineFormat(int flags, int width, int precision)
+ throws IOException
+ {
+ checkFlags(flags, 0, 'n');
+ noPrecision(precision);
+ if (width != -1)
+ throw new IllegalFormatWidthException(width);
+ genericFormat(lineSeparator, flags, width, precision);
+ }
+
+ /**
+ * Helper method to do initial formatting and checking for integral
+ * conversions.
+ *
+ * @param arg the formatted argument.
+ * @param flags the formatting flags to use.
+ * @param width the width to use.
+ * @param precision the precision to use.
+ * @param radix the radix of the number.
+ * @param conversion the conversion character.
+ * @return the result.
+ */
+ private StringBuilder basicIntegralConversion(Object arg, int flags,
+ int width, int precision,
+ int radix, char conversion)
+ {
+ assert radix == 8 || radix == 10 || radix == 16;
+ noPrecision(precision);
+
+ // Some error checking.
+ if ((flags & FormattableFlags.ZERO) != 0
+ && (flags & FormattableFlags.LEFT_JUSTIFY) == 0)
+ throw new IllegalFormatFlagsException(getName(flags));
+ if ((flags & FormattableFlags.PLUS) != 0
+ && (flags & FormattableFlags.SPACE) != 0)
+ throw new IllegalFormatFlagsException(getName(flags));
+
+ if ((flags & FormattableFlags.LEFT_JUSTIFY) != 0 && width == -1)
+ throw new MissingFormatWidthException("fixme");
+
+ // Do the base translation of the value to a string.
+ String result;
+ int basicFlags = (FormattableFlags.LEFT_JUSTIFY
+ // We already handled any possible error when
+ // parsing.
+ | FormattableFlags.UPPERCASE
+ | FormattableFlags.ZERO);
+ if (radix == 10)
+ basicFlags |= (FormattableFlags.PLUS
+ | FormattableFlags.SPACE
+ | FormattableFlags.COMMA
+ | FormattableFlags.PAREN);
+ else
+ basicFlags |= FormattableFlags.ALTERNATE;
+
+ if (arg instanceof BigInteger)
+ {
+ checkFlags(flags,
+ (basicFlags
+ | FormattableFlags.PLUS
+ | FormattableFlags.SPACE
+ | FormattableFlags.PAREN),
+ conversion);
+ BigInteger bi = (BigInteger) arg;
+ result = bi.toString(radix);
+ }
+ else if (arg instanceof Number
+ && ! (arg instanceof Float)
+ && ! (arg instanceof Double))
+ {
+ checkFlags(flags, basicFlags, conversion);
+ long value = ((Number) arg).longValue ();
+ if (radix == 8)
+ result = Long.toOctalString(value);
+ else if (radix == 16)
+ result = Long.toHexString(value);
+ else
+ result = Long.toString(value);
+ }
+ else
+ throw new IllegalFormatConversionException(conversion, arg.getClass());
+
+ return new StringBuilder(result);
+ }
+
+ /**
+ * Emit a hex or octal value.
+ *
+ * @param arg the hexadecimal or octal value.
+ * @param flags the formatting flags to use.
+ * @param width the width to use.
+ * @param precision the precision to use.
+ * @param radix the radix of the number.
+ * @param conversion the conversion character.
+ * @throws IOException if the output stream throws an I/O error.
+ */
+ private void hexOrOctalConversion(Object arg, int flags, int width,
+ int precision, int radix,
+ char conversion)
+ throws IOException
+ {
+ assert radix == 8 || radix == 16;
+
+ StringBuilder builder = basicIntegralConversion(arg, flags, width,
+ precision, radix,
+ conversion);
+ int insertPoint = 0;
+
+ // Insert the sign.
+ if (builder.charAt(0) == '-')
+ {
+ // Already inserted. Note that we don't insert a sign, since
+ // the only case where it is needed it BigInteger, and it has
+ // already been inserted by toString.
+ ++insertPoint;
+ }
+ else if ((flags & FormattableFlags.PLUS) != 0)
+ {
+ builder.insert(insertPoint, '+');
+ ++insertPoint;
+ }
+ else if ((flags & FormattableFlags.SPACE) != 0)
+ {
+ builder.insert(insertPoint, ' ');
+ ++insertPoint;
+ }
+
+ // Insert the radix prefix.
+ if ((flags & FormattableFlags.ALTERNATE) != 0)
+ {
+ builder.insert(insertPoint, radix == 8 ? "0" : "0x");
+ insertPoint += radix == 8 ? 1 : 2;
+ }
+
+ // Now justify the result.
+ int resultWidth = builder.length();
+ if (resultWidth < width)
+ {
+ char fill = ((flags & FormattableFlags.ZERO) != 0) ? '0' : ' ';
+ if ((flags & FormattableFlags.LEFT_JUSTIFY) != 0)
+ {
+ // Left justify.
+ if (fill == ' ')
+ insertPoint = builder.length();
+ }
+ else
+ {
+ // Right justify. Insert spaces before the radix prefix
+ // and sign.
+ insertPoint = 0;
+ }
+ while (resultWidth++ < width)
+ builder.insert(insertPoint, fill);
+ }
+
+ String result = builder.toString();
+ if ((flags & FormattableFlags.UPPERCASE) != 0)
+ {
+ if (fmtLocale == null)
+ result = result.toUpperCase();
+ else
+ result = result.toUpperCase(fmtLocale);
+ }
+
+ out.append(result);
+ }
+
+ /**
+ * Emit a decimal value.
+ *
+ * @param arg the hexadecimal or octal value.
+ * @param flags the formatting flags to use.
+ * @param width the width to use.
+ * @param precision the precision to use.
+ * @param conversion the conversion character.
+ * @throws IOException if the output stream throws an I/O error.
+ */
+ private void decimalConversion(Object arg, int flags, int width,
+ int precision, char conversion)
+ throws IOException
+ {
+ StringBuilder builder = basicIntegralConversion(arg, flags, width,
+ precision, 10,
+ conversion);
+ boolean isNegative = false;
+ if (builder.charAt(0) == '-')
+ {
+ // Sign handling is done during localization.
+ builder.deleteCharAt(0);
+ isNegative = true;
+ }
+
+ applyLocalization(builder, flags, width, isNegative);
+ genericFormat(builder.toString(), flags, width, precision);
+ }
+
+ /**
+ * Emit a single date or time conversion to a StringBuilder.
+ *
+ * @param builder the builder to write to.
+ * @param cal the calendar to use in the conversion.
+ * @param conversion the formatting character to specify the type of data.
+ * @param syms the date formatting symbols.
+ */
+ private void singleDateTimeConversion(StringBuilder builder, Calendar cal,
+ char conversion,
+ DateFormatSymbols syms)
+ {
+ int oldLen = builder.length();
+ int digits = -1;
+ switch (conversion)
+ {
+ case 'H':
+ builder.append(cal.get(Calendar.HOUR_OF_DAY));
+ digits = 2;
+ break;
+ case 'I':
+ builder.append(cal.get(Calendar.HOUR));
+ digits = 2;
+ break;
+ case 'k':
+ builder.append(cal.get(Calendar.HOUR_OF_DAY));
+ break;
+ case 'l':
+ builder.append(cal.get(Calendar.HOUR));
+ break;
+ case 'M':
+ builder.append(cal.get(Calendar.MINUTE));
+ digits = 2;
+ break;
+ case 'S':
+ builder.append(cal.get(Calendar.SECOND));
+ digits = 2;
+ break;
+ case 'N':
+ // FIXME: nanosecond ...
+ digits = 9;
+ break;
+ case 'p':
+ {
+ int ampm = cal.get(Calendar.AM_PM);
+ builder.append(syms.getAmPmStrings()[ampm]);
+ }
+ break;
+ case 'z':
+ {
+ int zone = cal.get(Calendar.ZONE_OFFSET) / (1000 * 60);
+ builder.append(zone);
+ digits = 4;
+ // Skip the '-' sign.
+ if (zone < 0)
+ ++oldLen;
+ }
+ break;
+ case 'Z':
+ {
+ // FIXME: DST?
+ int zone = cal.get(Calendar.ZONE_OFFSET) / (1000 * 60 * 60);
+ String[][] zs = syms.getZoneStrings();
+ builder.append(zs[zone + 12][1]);
+ }
+ break;
+ case 's':
+ {
+ long val = cal.getTime().getTime();
+ builder.append(val / 1000);
+ }
+ break;
+ case 'Q':
+ {
+ long val = cal.getTime().getTime();
+ builder.append(val);
+ }
+ break;
+ case 'B':
+ {
+ int month = cal.get(Calendar.MONTH);
+ builder.append(syms.getMonths()[month]);
+ }
+ break;
+ case 'b':
+ case 'h':
+ {
+ int month = cal.get(Calendar.MONTH);
+ builder.append(syms.getShortMonths()[month]);
+ }
+ break;
+ case 'A':
+ {
+ int day = cal.get(Calendar.DAY_OF_WEEK);
+ builder.append(syms.getWeekdays()[day]);
+ }
+ break;
+ case 'a':
+ {
+ int day = cal.get(Calendar.DAY_OF_WEEK);
+ builder.append(syms.getShortWeekdays()[day]);
+ }
+ break;
+ case 'C':
+ builder.append(cal.get(Calendar.YEAR) / 100);
+ digits = 2;
+ break;
+ case 'Y':
+ builder.append(cal.get(Calendar.YEAR));
+ digits = 4;
+ break;
+ case 'y':
+ builder.append(cal.get(Calendar.YEAR) % 100);
+ digits = 2;
+ break;
+ case 'j':
+ builder.append(cal.get(Calendar.DAY_OF_YEAR));
+ digits = 3;
+ break;
+ case 'm':
+ builder.append(cal.get(Calendar.MONTH) + 1);
+ digits = 2;
+ break;
+ case 'd':
+ builder.append(cal.get(Calendar.DAY_OF_MONTH));
+ digits = 2;
+ break;
+ case 'e':
+ builder.append(cal.get(Calendar.DAY_OF_MONTH));
+ break;
+ case 'R':
+ singleDateTimeConversion(builder, cal, 'H', syms);
+ builder.append(':');
+ singleDateTimeConversion(builder, cal, 'M', syms);
+ break;
+ case 'T':
+ singleDateTimeConversion(builder, cal, 'H', syms);
+ builder.append(':');
+ singleDateTimeConversion(builder, cal, 'M', syms);
+ builder.append(':');
+ singleDateTimeConversion(builder, cal, 'S', syms);
+ break;
+ case 'r':
+ singleDateTimeConversion(builder, cal, 'I', syms);
+ builder.append(':');
+ singleDateTimeConversion(builder, cal, 'M', syms);
+ builder.append(':');
+ singleDateTimeConversion(builder, cal, 'S', syms);
+ builder.append(' ');
+ singleDateTimeConversion(builder, cal, 'p', syms);
+ break;
+ case 'D':
+ singleDateTimeConversion(builder, cal, 'm', syms);
+ builder.append('/');
+ singleDateTimeConversion(builder, cal, 'd', syms);
+ builder.append('/');
+ singleDateTimeConversion(builder, cal, 'y', syms);
+ break;
+ case 'F':
+ singleDateTimeConversion(builder, cal, 'Y', syms);
+ builder.append('-');
+ singleDateTimeConversion(builder, cal, 'm', syms);
+ builder.append('-');
+ singleDateTimeConversion(builder, cal, 'd', syms);
+ break;
+ case 'c':
+ singleDateTimeConversion(builder, cal, 'a', syms);
+ builder.append(' ');
+ singleDateTimeConversion(builder, cal, 'b', syms);
+ builder.append(' ');
+ singleDateTimeConversion(builder, cal, 'd', syms);
+ builder.append(' ');
+ singleDateTimeConversion(builder, cal, 'T', syms);
+ builder.append(' ');
+ singleDateTimeConversion(builder, cal, 'Z', syms);
+ builder.append(' ');
+ singleDateTimeConversion(builder, cal, 'Y', syms);
+ break;
+ default:
+ throw new UnknownFormatConversionException(String.valueOf(conversion));
+ }
+
+ if (digits > 0)
+ {
+ int newLen = builder.length();
+ int delta = newLen - oldLen;
+ while (delta++ < digits)
+ builder.insert(oldLen, '0');
+ }
+ }
+
+ /**
+ * Emit a date or time value.
+ *
+ * @param arg the date or time value.
+ * @param flags the formatting flags to use.
+ * @param width the width to use.
+ * @param precision the precision to use.
+ * @param conversion the conversion character.
+ * @param subConversion the sub conversion character.
+ * @throws IOException if the output stream throws an I/O error.
+ */
+ private void dateTimeConversion(Object arg, int flags, int width,
+ int precision, char conversion,
+ char subConversion)
+ throws IOException
+ {
+ noPrecision(precision);
+ checkFlags(flags,
+ FormattableFlags.LEFT_JUSTIFY | FormattableFlags.UPPERCASE,
+ conversion);
+
+ Calendar cal;
+ if (arg instanceof Calendar)
+ cal = (Calendar) arg;
+ else
+ {
+ Date date;
+ if (arg instanceof Date)
+ date = (Date) arg;
+ else if (arg instanceof Long)
+ date = new Date(((Long) arg).longValue());
+ else
+ throw new IllegalFormatConversionException(conversion,
+ arg.getClass());
+ if (fmtLocale == null)
+ cal = Calendar.getInstance();
+ else
+ cal = Calendar.getInstance(fmtLocale);
+ cal.setTime(date);
+ }
+
+ // We could try to be more efficient by computing this lazily.
+ DateFormatSymbols syms;
+ if (fmtLocale == null)
+ syms = new DateFormatSymbols();
+ else
+ syms = new DateFormatSymbols(fmtLocale);
+
+ StringBuilder result = new StringBuilder();
+ singleDateTimeConversion(result, cal, subConversion, syms);
+
+ genericFormat(result.toString(), flags, width, precision);
+ }
+
+ /**
+ * Advance the internal parsing index, and throw an exception
+ * on overrun.
+ *
+ * @throws IllegalArgumentException on overrun.
+ */
+ private void advance()
+ {
+ ++index;
+ if (index >= length)
+ {
+ // FIXME: what exception here?
+ throw new IllegalArgumentException();
+ }
+ }
+
+ /**
+ * Parse an integer appearing in the format string. Will return -1
+ * if no integer was found.
+ *
+ * @return the parsed integer.
+ */
+ private int parseInt()
+ {
+ int start = index;
+ while (Character.isDigit(format.charAt(index)))
+ advance();
+ if (start == index)
+ return -1;
+ return Integer.decode(format.substring(start, index)).intValue();
+ }
+
+ /**
+ * Parse the argument index. Returns -1 if there was no index, 0 if
+ * we should re-use the previous index, and a positive integer to
+ * indicate an absolute index.
+ *
+ * @return the parsed argument index.
+ */
+ private int parseArgumentIndex()
+ {
+ int result = -1;
+ int start = index;
+ if (format.charAt(index) == '<')
+ {
+ result = 0;
+ advance();
+ }
+ else if (Character.isDigit(format.charAt(index)))
+ {
+ result = parseInt();
+ if (format.charAt(index) == '$')
+ advance();
+ else
+ {
+ // Reset.
+ index = start;
+ result = -1;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Parse a set of flags and return a bit mask of values from
+ * FormattableFlags. Will throw an exception if a flag is
+ * duplicated.
+ *
+ * @return the parsed flags.
+ */
+ private int parseFlags()
+ {
+ int value = 0;
+ int start = index;
+ while (true)
+ {
+ int x = FLAGS.indexOf(format.charAt(index));
+ if (x == -1)
+ break;
+ int newValue = 1 << x;
+ if ((value & newValue) != 0)
+ throw new DuplicateFormatFlagsException(format.substring(start,
+ index + 1));
+ value |= newValue;
+ advance();
+ }
+ return value;
+ }
+
+ /**
+ * Parse the width part of a format string. Returns -1 if no width
+ * was specified.
+ *
+ * @return the parsed width.
+ */
+ private int parseWidth()
+ {
+ return parseInt();
+ }
+
+ /**
+ * If the current character is '.', parses the precision part of a
+ * format string. Returns -1 if no precision was specified.
+ *
+ * @return the parsed precision.
+ */
+ private int parsePrecision()
+ {
+ if (format.charAt(index) != '.')
+ return -1;
+ advance();
+ int precision = parseInt();
+ if (precision == -1)
+ // FIXME
+ throw new IllegalArgumentException();
+ return precision;
+ }
+
+ /**
+ * Outputs a formatted string based on the supplied specification,
+ * <code>fmt</code>, and its arguments using the specified locale.
+ * The locale of the formatter does not change as a result; the
+ * specified locale is just used for this particular formatting
+ * operation. If the locale is <code>null</code>, then no
+ * localization is applied.
+ *
+ * @param loc the locale to use for this format.
+ * @param fmt the format specification.
+ * @param args the arguments to apply to the specification.
+ * @throws IllegalFormatException if there is a problem with
+ * the syntax of the format
+ * specification or a mismatch
+ * between it and the arguments.
+ * @throws FormatterClosedException if the formatter is closed.
+ */
+ public Formatter format(Locale loc, String fmt, Object[] args)
+ {
+ if (closed)
+ throw new FormatterClosedException();
+
+ // Note the arguments are indexed starting at 1.
+ int implicitArgumentIndex = 1;
+ int previousArgumentIndex = 0;
+
+ try
+ {
+ fmtLocale = loc;
+ format = fmt;
+ length = format.length();
+ for (index = 0; index < length; ++index)
+ {
+ char c = format.charAt(index);
+ if (c != '%')
+ {
+ out.append(c);
+ continue;
+ }
+
+ int start = index;
+ advance();
+
+ // We do the needed post-processing of this later, when we
+ // determine whether an argument is actually needed by
+ // this conversion.
+ int argumentIndex = parseArgumentIndex();
+
+ int flags = parseFlags();
+ int width = parseWidth();
+ int precision = parsePrecision();
+ char origConversion = format.charAt(index);
+ char conversion = origConversion;
+ if (Character.isUpperCase(conversion))
+ {
+ flags |= FormattableFlags.UPPERCASE;
+ conversion = Character.toLowerCase(conversion);
+ }
+
+ Object argument = null;
+ if (conversion == '%' || conversion == 'n')
+ {
+ if (argumentIndex != -1)
+ {
+ // FIXME: not sure about this.
+ throw new UnknownFormatConversionException("FIXME");
+ }
+ }
+ else
+ {
+ if (argumentIndex == -1)
+ argumentIndex = implicitArgumentIndex++;
+ else if (argumentIndex == 0)
+ argumentIndex = previousArgumentIndex;
+ // Argument indices start at 1 but array indices at 0.
+ --argumentIndex;
+ if (argumentIndex < 0 || argumentIndex >= args.length)
+ throw new MissingFormatArgumentException(format.substring(start, index));
+ argument = args[argumentIndex];
+ }
+
+ switch (conversion)
+ {
+ case 'b':
+ booleanFormat(argument, flags, width, precision,
+ origConversion);
+ break;
+ case 'h':
+ hashCodeFormat(argument, flags, width, precision,
+ origConversion);
+ break;
+ case 's':
+ stringFormat(argument, flags, width, precision,
+ origConversion);
+ break;
+ case 'c':
+ characterFormat(argument, flags, width, precision,
+ origConversion);
+ break;
+ case 'd':
+ checkFlags(flags & FormattableFlags.UPPERCASE, 0, 'd');
+ decimalConversion(argument, flags, width, precision,
+ origConversion);
+ break;
+ case 'o':
+ checkFlags(flags & FormattableFlags.UPPERCASE, 0, 'o');
+ hexOrOctalConversion(argument, flags, width, precision, 8,
+ origConversion);
+ break;
+ case 'x':
+ hexOrOctalConversion(argument, flags, width, precision, 16,
+ origConversion);
+ case 'e':
+ // scientificNotationConversion();
+ break;
+ case 'f':
+ // floatingDecimalConversion();
+ break;
+ case 'g':
+ // smartFloatingConversion();
+ break;
+ case 'a':
+ // hexFloatingConversion();
+ break;
+ case 't':
+ advance();
+ char subConversion = format.charAt(index);
+ dateTimeConversion(argument, flags, width, precision,
+ origConversion, subConversion);
+ break;
+ case '%':
+ percentFormat(flags, width, precision);
+ break;
+ case 'n':
+ newLineFormat(flags, width, precision);
+ break;
+ default:
+ throw new UnknownFormatConversionException(String.valueOf(origConversion));
+ }
+ }
+ }
+ catch (IOException exc)
+ {
+ ioException = exc;
+ }
+ return this;
+ }
+
+ /**
+ * Outputs a formatted string based on the supplied specification,
+ * <code>fmt</code>, and its arguments using the formatter's locale.
+ *
+ * @param fmt the format specification.
+ * @param args the arguments to apply to the specification.
+ * @throws IllegalFormatException if there is a problem with
+ * the syntax of the format
+ * specification or a mismatch
+ * between it and the arguments.
+ * @throws FormatterClosedException if the formatter is closed.
+ */
+ public Formatter format(String format, Object[] args)
+ {
+ return format(locale, format, args);
+ }
+
+ /**
+ * Returns the last I/O exception thrown by the
+ * <code>append()</code> operation of the underlying
+ * output stream.
+ *
+ * @return the last I/O exception.
+ */
+ public IOException ioException()
+ {
+ return ioException;
+ }
+
+ /**
+ * Returns the locale used by this formatter.
+ *
+ * @return the formatter's locale.
+ * @throws FormatterClosedException if the formatter is closed.
+ */
+ public Locale locale()
+ {
+ if (closed)
+ throw new FormatterClosedException();
+ return locale;
+ }
+
+ /**
+ * Returns the output stream used by this formatter.
+ *
+ * @return the formatter's output stream.
+ * @throws FormatterClosedException if the formatter is closed.
+ */
+ public StringBuilder out()
+ {
+ if (closed)
+ throw new FormatterClosedException();
+ return out;
+ }
+
+ /**
+ * Returns the result of applying {@link Object#toString()}
+ * to the underlying output stream. The results returned
+ * depend on the particular {@link Appendable} being used.
+ * For example, a {@link StringBuilder} will return the
+ * formatted output but an I/O stream will not.
+ *
+ * @throws FormatterClosedException if the formatter is closed.
+ */
+ public String toString()
+ {
+ if (closed)
+ throw new FormatterClosedException();
+ return out.toString();
+ }
+}
diff --git a/java/util/FormatterClosedException.java b/java/util/FormatterClosedException.java
new file mode 100644
index 000000000..c3588648e
--- /dev/null
+++ b/java/util/FormatterClosedException.java
@@ -0,0 +1,60 @@
+/* FormatterClosedException.java
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.util;
+
+/**
+ * Thrown when a method is called on a {@link Formatter} but
+ * it has already been closed.
+ *
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+public class FormatterClosedException
+ extends IllegalStateException
+{
+ private static final long serialVersionUID = 18111216L;
+
+ /**
+ * Constructs a new <code>FormatterClosedException</code>.
+ */
+ public FormatterClosedException()
+ {
+ }
+}
diff --git a/java/util/IllegalFormatCodePointException.java b/java/util/IllegalFormatCodePointException.java
new file mode 100644
index 000000000..001839fe1
--- /dev/null
+++ b/java/util/IllegalFormatCodePointException.java
@@ -0,0 +1,85 @@
+/* IllegalFormatCodePointException.java
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.util;
+
+/**
+ * Thrown when a {@link Formatter} receives a character with an
+ * invalid Unicode codepoint, as defined by
+ * {@link Character#isValidCodePoint(int)}.
+ *
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+public class IllegalFormatCodePointException
+ extends IllegalFormatException
+{
+ private static final long serialVersionUID = 19080630L;
+
+ /**
+ * The character which is an invalid Unicode code point.
+ *
+ * @serial the invalid character.
+ */
+ // Note: name fixed by serialization.
+ int c;
+
+ /**
+ * Constructs a new <code>IllegalFormatCodePointException</code>
+ * which specifies that the character, <code>c</code>, passed to
+ * a {@link Formatter} is an invalid Unicode code point.
+ *
+ * @param c the invalid character.
+ */
+ public IllegalFormatCodePointException(int c)
+ {
+ super("An invalid Unicode code point was supplied.");
+ this.c = c;
+ }
+
+ /**
+ * Returns the invalid character.
+ *
+ * @return the invalid character.
+ */
+ public int getCodePoint()
+ {
+ return c;
+ }
+}
diff --git a/java/util/IllegalFormatConversionException.java b/java/util/IllegalFormatConversionException.java
new file mode 100644
index 000000000..2f981f26e
--- /dev/null
+++ b/java/util/IllegalFormatConversionException.java
@@ -0,0 +1,110 @@
+/* IllegalFormatConversionException.java
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.util;
+
+/**
+ * Thrown when the type of an argument supplied to the
+ * {@link Formatter#format()} method of a {@link Formatter}
+ * does not match the conversion character specified for it.
+ *
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+public class IllegalFormatConversionException
+ extends IllegalFormatException
+{
+ private static final long serialVersionUID = 17000126L;
+
+ /**
+ * The conversion character which doesn't match
+ * the type of the argument.
+ *
+ * @serial the conversion character.
+ */
+ // Note: name fixed by serialization.
+ char c;
+
+ /**
+ * The type of the mismatching argument.
+ *
+ * @serial the mismatching argument type.
+ */
+ // Note: name fixed by serialization.
+ Class arg;
+
+ /**
+ * Constructs a new <code>IllegalFormatConversionException</code>
+ * which specifies that the argument of type <code>arg</code> does
+ * not match the conversion character, <code>c</code>.
+ *
+ * @param c the conversion character.
+ * @param arg the type which doesn't match the conversion character.
+ * @throws NullPointerException if <code>arg</code> is null.
+ */
+ public IllegalFormatConversionException(char c, Class arg)
+ {
+ super("The type, " + arg + ", is invalid for the conversion character, " +
+ c + ".");
+ if (arg == null)
+ throw new NullPointerException("The supplied type was null.");
+ this.c = c;
+ this.arg = arg;
+ }
+
+ /**
+ * Returns the conversion character.
+ *
+ * @return the conversion character.
+ */
+ public char getConversion()
+ {
+ return c;
+ }
+
+ /**
+ * Returns the type of the mismatched argument.
+ *
+ * @return the type of the mismatched argument.
+ */
+ public Class getArgumentClass()
+ {
+ return arg;
+ }
+}
diff --git a/java/util/IllegalFormatException.java b/java/util/IllegalFormatException.java
new file mode 100644
index 000000000..4daafca44
--- /dev/null
+++ b/java/util/IllegalFormatException.java
@@ -0,0 +1,75 @@
+/* IllegalFormatException.java
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.util;
+
+/**
+ * A general exception thrown when a format string is supplied
+ * to a {@link Formatter} that contains either invalid syntax
+ * or a mismatch between the format specification and the
+ * supplied arguments. This class is never instantiated;
+ * instead one of its subclasses is used to throw a more
+ * specific exception.
+ *
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+public class IllegalFormatException
+ extends IllegalArgumentException
+{
+ private static final long serialVersionUID = 18830826L;
+
+ /**
+ * Constructs a new <code>IllegalFormatException</code>.
+ */
+ IllegalFormatException()
+ {
+ }
+
+ /**
+ * Constructs a new <code>IllegalFormatException</code>
+ * with the specified message.
+ *
+ * @param msg the error message for this exception.
+ */
+ IllegalFormatException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/java/util/IllegalFormatFlagsException.java b/java/util/IllegalFormatFlagsException.java
new file mode 100644
index 000000000..2a085c141
--- /dev/null
+++ b/java/util/IllegalFormatFlagsException.java
@@ -0,0 +1,86 @@
+/* IllegalFormatFlagsException.java
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.util;
+
+/**
+ * Thrown when the flags supplied to the {@link Formatter#format()}
+ * method of a {@link Formatter} form an illegal combination.
+ *
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+public class IllegalFormatFlagsException
+ extends IllegalFormatException
+{
+ private static final long serialVersionUID = 790824L;
+
+ /**
+ * The set of flags which forms an illegal combination.
+ *
+ * @serial the illegal set of flags.
+ */
+ // Note: name fixed by serialization.
+ private String flags;
+
+ /**
+ * Constructs a new <code>IllegalFormatFlagsException</code>
+ * for the specified flags.
+ *
+ * @param flags the illegal set of flags.
+ * @throws NullPointerException if <code>flags</code> is null.
+ */
+ public IllegalFormatFlagsException(String flags)
+ {
+ super("An illegal set of flags, " + flags + ", was supplied.");
+ if (flags == null)
+ throw new NullPointerException("The supplied flags are null.");
+ this.flags = flags;
+ }
+
+ /**
+ * Returns the illegal flags.
+ *
+ * @return the illegal flags.
+ */
+ public String getFlags()
+ {
+ return flags;
+ }
+}
diff --git a/java/util/IllegalFormatPrecisionException.java b/java/util/IllegalFormatPrecisionException.java
new file mode 100644
index 000000000..a555f5df4
--- /dev/null
+++ b/java/util/IllegalFormatPrecisionException.java
@@ -0,0 +1,85 @@
+/* IllegalFormatPrecisionException.java
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.util;
+
+/**
+ * Thrown when the specified precision for a {@link Formatter}
+ * argument is illegal. This may be because the number is
+ * a negative number (other than -1), the argument does not
+ * accept a precision or for some other reason.
+ *
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+public class IllegalFormatPrecisionException
+ extends IllegalFormatException
+{
+ private static final long serialVersionUID = 18711008L;
+
+ /**
+ * The illegal precision value.
+ *
+ * @serial the illegal precision.
+ */
+ // Note: name fixed by serialization.
+ private int p;
+
+ /**
+ * Constructs a new <code>IllegalFormatPrecisionException</code>
+ * for the precision, <code>p</code>.
+ *
+ * @param p the illegal precision.
+ */
+ public IllegalFormatPrecisionException(int p)
+ {
+ super("The precision, " + p + ", is illegal.");
+ this.p = p;
+ }
+
+ /**
+ * Returns the illegal precision.
+ *
+ * @return the illegal precision.
+ */
+ public int getPrecision()
+ {
+ return p;
+ }
+}
diff --git a/java/util/IllegalFormatWidthException.java b/java/util/IllegalFormatWidthException.java
new file mode 100644
index 000000000..95d3e1502
--- /dev/null
+++ b/java/util/IllegalFormatWidthException.java
@@ -0,0 +1,84 @@
+/* IllegalFormatWidthException.java
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.util;
+
+/**
+ * Thrown when the specified width for a {@link Formatter}
+ * argument is illegal. This may be because the number is
+ * a negative number (other than -1) or for some other reason.
+ *
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+public class IllegalFormatWidthException
+ extends IllegalFormatException
+{
+ private static final long serialVersionUID = 16660902L;
+
+ /**
+ * The illegal width value.
+ *
+ * @serial the illegal width.
+ */
+ // Note: name fixed by serialization.
+ private int w;
+
+ /**
+ * Constructs a new <code>IllegalFormatWidthException</code>
+ * with the specified width, <code>w</code>.
+ *
+ * @param w the illegal width.
+ */
+ public IllegalFormatWidthException(int w)
+ {
+ super("The width, " + w + ", is illegal.");
+ this.w = w;
+ }
+
+ /**
+ * Returns the illegal width.
+ *
+ * @return the illegal width.
+ */
+ public int getWidth()
+ {
+ return w;
+ }
+}
diff --git a/java/util/MissingFormatArgumentException.java b/java/util/MissingFormatArgumentException.java
new file mode 100644
index 000000000..4a9385ed5
--- /dev/null
+++ b/java/util/MissingFormatArgumentException.java
@@ -0,0 +1,90 @@
+/* MissingFormatArgumentException.java
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.util;
+
+/**
+ * Thrown when the a format specification for a {@link Formatter}
+ * refers to an argument that is non-existent, or an argument index
+ * references a non-existent argument.
+ *
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+public class MissingFormatArgumentException
+ extends IllegalFormatException
+{
+ private static final long serialVersionUID = 19190115L;
+
+ /**
+ * The format specification which contains the
+ * unmatched argument.
+ *
+ * @serial the format specification.
+ */
+ // Note: name fixed by serialization.
+ private String s;
+
+ /**
+ * Constructs a new <code>MissingFormatArgumentException</code>
+ * for a format specification, <code>s</code>, which refers
+ * to a non-existent argument.
+ *
+ * @param s the format specification.
+ * @throws NullPointerException if <code>s</code> is null.
+ */
+ public MissingFormatArgumentException(String s)
+ {
+ super("The specification, " + s +
+ ", refers to a non-existent argument.");
+ if (s == null)
+ throw new NullPointerException("The specification is null.");
+ this.s = s;
+ }
+
+ /**
+ * Returns the format specification.
+ *
+ * @return the format specification.
+ */
+ public String getFormatSpecifier()
+ {
+ return s;
+ }
+}
diff --git a/java/util/MissingFormatWidthException.java b/java/util/MissingFormatWidthException.java
new file mode 100644
index 000000000..55de6202f
--- /dev/null
+++ b/java/util/MissingFormatWidthException.java
@@ -0,0 +1,88 @@
+/* MissingFormatWidthException.java
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.util;
+
+/**
+ * Thrown when the a format specification for a {@link Formatter}
+ * does not include a width for a value where one is required.
+ *
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+public class MissingFormatWidthException
+ extends IllegalFormatException
+{
+ private static final long serialVersionUID = 15560123L;
+
+ /**
+ * The format specification which contains the
+ * unmatched argument.
+ *
+ * @serial the format specification.
+ */
+ // Note: name fixed by serialization.
+ private String s;
+
+ /**
+ * Constructs a new <code>MissingFormatWidthException</code>
+ * for a format specification, <code>s</code>, which excludes
+ * a required width argument.
+ *
+ * @param s the format specification.
+ * @throws NullPointerException if <code>s</code> is null.
+ */
+ public MissingFormatWidthException(String s)
+ {
+ super("The specification, " + s + ", misses a required width.");
+ if (s == null)
+ throw new NullPointerException("The specification is null.");
+ this.s = s;
+ }
+
+ /**
+ * Returns the format specification.
+ *
+ * @return the format specification.
+ */
+ public String getFormatSpecifier()
+ {
+ return s;
+ }
+}
diff --git a/java/util/SimpleTimeZone.java b/java/util/SimpleTimeZone.java
index 72d61ff19..d94f89ad3 100644
--- a/java/util/SimpleTimeZone.java
+++ b/java/util/SimpleTimeZone.java
@@ -333,6 +333,8 @@ public class SimpleTimeZone extends TimeZone
setStartRule(startMonth, startDayOfWeekInMonth, startDayOfWeek, startTime);
setEndRule(endMonth, endDayOfWeekInMonth, endDayOfWeek, endTime);
+ if (startMonth == endMonth)
+ throw new IllegalArgumentException("startMonth and endMonth must be different");
this.startYear = 0;
}
@@ -391,6 +393,8 @@ public class SimpleTimeZone extends TimeZone
setStartRule(startMonth, startDayOfWeekInMonth, startDayOfWeek, startTime);
setEndRule(endMonth, endDayOfWeekInMonth, endDayOfWeek, endTime);
+ if (startMonth == endMonth)
+ throw new IllegalArgumentException("startMonth and endMonth must be different");
this.startYear = 0;
this.dstSavings = dstSavings;
@@ -409,66 +413,67 @@ public class SimpleTimeZone extends TimeZone
}
/**
- * Checks if the values are in range and
+ * Checks if the month, day, dayOfWeek arguments are in range and
* returns the mode of the rule.
* @param month the month parameter as in the constructor
+ * @param day the day parameter as in the constructor
+ * @param dayOfWeek the day of week parameter as in the constructor
* @return the mode of this rule see startMode.
* @exception IllegalArgumentException if parameters are out of range.
* @see #SimpleTimeZone(int, String, int, int, int, int, int, int, int, int)
* @see #startMode
*/
- private int checkRule(int month)
+ private int checkRule(int month, int day, int dayOfWeek)
{
- if (startDay != 0)
+ if (month < 0 || month > 11)
+ throw new IllegalArgumentException("month out of range");
+
+ int daysInMonth = getDaysInMonth(month, 1);
+ if (dayOfWeek == 0)
+ {
+ if (day <= 0 || day > daysInMonth)
+ throw new IllegalArgumentException("day out of range");
+ return DOM_MODE;
+ }
+ else if (dayOfWeek > 0)
{
- if (startMonth < 0 || startMonth > 11)
- throw new IllegalArgumentException("month out of range");
-
- if (startDayOfWeek == 0)
- startMode = DOM_MODE;
- else
- {
- if (startDayOfWeek > 0)
- startMode = DOW_IN_MONTH_MODE;
- else
- {
- startDayOfWeek = -startDayOfWeek;
- if (startDay < 0)
- {
- startDay = - startDay;
- startMode = DOW_LE_DOM_MODE;
- }
- else
- startMode = DOW_GE_DOM_MODE;
- }
-
- if (startDayOfWeek > Calendar.SATURDAY)
- throw new IllegalArgumentException("day of week out of range");
- }
-
- if (startMode != DOW_IN_MONTH_MODE
- && (startDay <= 0 || startDay > getDaysInMonth(month, 1)))
- throw new IllegalArgumentException("day out of range");
+ if (Math.abs(day) > (daysInMonth + 6) / 7)
+ throw new IllegalArgumentException("dayOfWeekInMonth out of range");
+ if (dayOfWeek > Calendar.SATURDAY)
+ throw new IllegalArgumentException("dayOfWeek out of range");
+ return DOW_IN_MONTH_MODE;
+ }
+ else
+ {
+ if (day == 0 || Math.abs(day) > daysInMonth)
+ throw new IllegalArgumentException("day out of range");
+ if (dayOfWeek < -Calendar.SATURDAY)
+ throw new IllegalArgumentException("dayOfWeek out of range");
+ if (day < 0)
+ return DOW_LE_DOM_MODE;
+ else
+ return DOW_GE_DOM_MODE;
}
- return startMode;
}
/**
- * Sets the daylight savings start rule. You must also set the end rule with
- * <code>setEndRule</code> or the result of getOffset is undefined. For the
- * parameters see the ten-argument constructor above.
- *
- * @param month The month where daylight savings start, zero based. You should
- * use the constants in Calendar.
+ * Sets the daylight savings start rule. You must also set the
+ * end rule with <code>setEndRule</code> or the result of
+ * getOffset is undefined. For the parameters see the ten-argument
+ * constructor above.
+ *
+ * @param month The month where daylight savings start, zero
+ * based. You should use the constants in Calendar.
* @param day A day of month or day of week in month.
* @param dayOfWeek The day of week where daylight savings start.
- * @param time The time in milliseconds standard time where daylight savings
- * start.
+ * @param time The time in milliseconds standard time where daylight
+ * savings start.
* @exception IllegalArgumentException if parameters are out of range.
* @see SimpleTimeZone
*/
public void setStartRule(int month, int day, int dayOfWeek, int time)
{
+ this.startMode = checkRule(month, day, dayOfWeek);
this.startMonth = month;
this.startDay = day;
this.startDayOfWeek = Math.abs(dayOfWeek);
@@ -478,7 +483,6 @@ public class SimpleTimeZone extends TimeZone
// Convert from UTC to STANDARD
this.startTime = time + this.rawOffset;
useDaylight = true;
- this.startMode = checkRule(month);
}
/**
@@ -513,6 +517,9 @@ public class SimpleTimeZone extends TimeZone
// or before mode.
this.startDay = after ? Math.abs(day) : -Math.abs(day);
this.startDayOfWeek = after ? Math.abs(dayOfWeek) : -Math.abs(dayOfWeek);
+ this.startMode = (dayOfWeek != 0)
+ ? (after ? DOW_GE_DOM_MODE : DOW_LE_DOM_MODE)
+ : checkRule(month, day, dayOfWeek);
this.startDay = Math.abs(this.startDay);
this.startDayOfWeek = Math.abs(this.startDayOfWeek);
@@ -524,9 +531,6 @@ public class SimpleTimeZone extends TimeZone
// Convert from UTC to STANDARD
this.startTime = time + this.rawOffset;
useDaylight = true;
- this.startMode = (dayOfWeek != 0)
- ? (after ? DOW_GE_DOM_MODE : DOW_LE_DOM_MODE)
- : checkRule(month);
}
/**
@@ -562,6 +566,7 @@ public class SimpleTimeZone extends TimeZone
*/
public void setEndRule(int month, int day, int dayOfWeek, int time)
{
+ this.endMode = checkRule(month, day, dayOfWeek);
this.endMonth = month;
this.endDay = day;
this.endDayOfWeek = Math.abs(dayOfWeek);
@@ -574,7 +579,6 @@ public class SimpleTimeZone extends TimeZone
// Convert from UTC to DST
this.endTime = time + this.rawOffset + this.dstSavings;
useDaylight = true;
- this.endMode = checkRule(month);
}
/**
@@ -607,6 +611,9 @@ public class SimpleTimeZone extends TimeZone
// or before mode.
this.endDay = after ? Math.abs(day) : -Math.abs(day);
this.endDayOfWeek = after ? Math.abs(dayOfWeek) : -Math.abs(dayOfWeek);
+ this.endMode = (dayOfWeek != 0)
+ ? (after ? DOW_GE_DOM_MODE : DOW_LE_DOM_MODE)
+ : checkRule(month, day, dayOfWeek);
this.endDay = Math.abs(this.endDay);
this.endDayOfWeek = Math.abs(endDayOfWeek);
@@ -621,9 +628,6 @@ public class SimpleTimeZone extends TimeZone
// Convert from UTC to DST
this.endTime = time + this.rawOffset + this.dstSavings;
useDaylight = true;
- this.endMode = (dayOfWeek != 0)
- ? (after ? DOW_GE_DOM_MODE : DOW_LE_DOM_MODE)
- : checkRule(month);
}
/**
@@ -770,7 +774,7 @@ public class SimpleTimeZone extends TimeZone
* @param year The year.
*/
private int getDaysInMonth(int month, int year)
- {
+ {
if (month == Calendar.FEBRUARY)
{
if ((year & 3) != 0)
diff --git a/java/util/UnknownFormatConversionException.java b/java/util/UnknownFormatConversionException.java
new file mode 100644
index 000000000..e37d9d356
--- /dev/null
+++ b/java/util/UnknownFormatConversionException.java
@@ -0,0 +1,86 @@
+/* UnknownFormatConversionException.java
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.util;
+
+/**
+ * Thrown when a {@link Formatter} is supplied with an
+ * unknown conversion.
+ *
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+public class UnknownFormatConversionException
+ extends IllegalFormatException
+{
+ private static final long serialVersionUID = 19060418L;
+
+ /**
+ * The unknown conversion.
+ *
+ * @serial the unknown conversion.
+ */
+ // Note: name fixed by serialization.
+ private String s;
+
+ /**
+ * Constructs a new <code>UnknownFormatConversionException</code>
+ * for the specified conversion string.
+ *
+ * @param s the conversion string.
+ * @throws NullPointerException if the conversion string is null.
+ */
+ public UnknownFormatConversionException(String s)
+ {
+ super("Unknown format conversion: " + s);
+ if (s == null)
+ throw new NullPointerException("The conversion string is null.");
+ this.s = s;
+ }
+
+ /**
+ * Returns the conversion string.
+ *
+ * @return the conversion string.
+ */
+ public String getConversion()
+ {
+ return s;
+ }
+}
diff --git a/java/util/UnknownFormatFlagsException.java b/java/util/UnknownFormatFlagsException.java
new file mode 100644
index 000000000..b8f939ec4
--- /dev/null
+++ b/java/util/UnknownFormatFlagsException.java
@@ -0,0 +1,88 @@
+/* UnknownFormatFlagsException.java
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.util;
+
+/**
+ * Thrown when a {@link Formatter} is supplied with an
+ * unknown flag.
+ *
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+public class UnknownFormatFlagsException
+ extends IllegalFormatException
+{
+ private static final long serialVersionUID = 19370506L;
+
+ /**
+ * The set of flags containing the unknown flag.
+ *
+ * @serial the unknown conversion.
+ */
+ // Note: name fixed by serialization.
+ private String flags;
+
+ /**
+ * Constructs a new <code>UnknownFormatFlagsException</code>
+ * which specifies that the supplied set of flags contains a
+ * unknown.
+ *
+ * @param flags the flags containing a unknown.
+ * @throws NullPointerException if <code>flags</code> is null.
+ */
+ public UnknownFormatFlagsException(String s)
+ {
+ super("Unknown flag passed in " + s);
+ if (s == null)
+ throw new
+ NullPointerException("Null flags value passed to constructor.");
+ this.flags = s;
+ }
+
+ /**
+ * Returns the flags which contain a unknown.
+ *
+ * @return the flags.
+ */
+ public String getFlags()
+ {
+ return flags;
+ }
+}
diff --git a/java/util/jar/JarOutputStream.java b/java/util/jar/JarOutputStream.java
index 2c8c2f08d..46c71b38c 100644
--- a/java/util/jar/JarOutputStream.java
+++ b/java/util/jar/JarOutputStream.java
@@ -101,7 +101,7 @@ public class JarOutputStream extends ZipOutputStream
/**
* Prepares the JarOutputStream for writing the next entry.
- * This implementation just calls <code>super.putNextEntre()</code>.
+ * This implementation just calls <code>super.putNextEntry()</code>.
*
* @param entry The information for the next entry
* @exception IOException when some unexpected I/O exception occurred
diff --git a/java/util/jar/Manifest.java b/java/util/jar/Manifest.java
index aa869f4c4..64a0c476a 100644
--- a/java/util/jar/Manifest.java
+++ b/java/util/jar/Manifest.java
@@ -1,4 +1,4 @@
-/* Manifest.java -- Reads, writes and manipulaties jar manifest files
+/* Manifest.java -- Reads, writes and manipulates jar manifest files
Copyright (C) 2000, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -152,7 +152,7 @@ public class Manifest implements Cloneable
}
/**
- * Read and merge a <code>Mainfest</code> from the designated input stream.
+ * Read and merge a <code>Manifest</code> from the designated input stream.
*
* @param in the input stream to read from.
* @throws IOException if an I/O related exception occurs during the process.
diff --git a/java/util/logging/FileHandler.java b/java/util/logging/FileHandler.java
index cde861916..357d51e14 100644
--- a/java/util/logging/FileHandler.java
+++ b/java/util/logging/FileHandler.java
@@ -192,6 +192,42 @@ public class FileHandler
extends StreamHandler
{
/**
+ * A literal that prefixes all file-handler related properties in the
+ * logging.properties file.
+ */
+ private static final String PROPERTY_PREFIX = "java.util.logging.FileHandler";
+ /**
+ * The name of the property to set for specifying a file naming (incl. path)
+ * pattern to use with rotating log files.
+ */
+ private static final String PATTERN_KEY = PROPERTY_PREFIX + ".pattern";
+ /**
+ * The default pattern to use when the <code>PATTERN_KEY</code> property was
+ * not specified in the logging.properties file.
+ */
+ private static final String DEFAULT_PATTERN = "%h/java%u.log";
+ /**
+ * The name of the property to set for specifying an approximate maximum
+ * amount, in bytes, to write to any one log output file. A value of zero
+ * (which is the default) implies a no limit.
+ */
+ private static final String LIMIT_KEY = PROPERTY_PREFIX + ".limit";
+ private static final int DEFAULT_LIMIT = 0;
+ /**
+ * The name of the property to set for specifying how many output files to
+ * cycle through. The default value is 1.
+ */
+ private static final String COUNT_KEY = PROPERTY_PREFIX + ".count";
+ private static final int DEFAULT_COUNT = 1;
+ /**
+ * The name of the property to set for specifying whether this handler should
+ * append, or not, its output to existing files. The default value is
+ * <code>false</code> meaning NOT to append.
+ */
+ private static final String APPEND_KEY = PROPERTY_PREFIX + ".append";
+ private static final boolean DEFAULT_APPEND = false;
+
+ /**
* The number of bytes a log file is approximately allowed to reach
* before it is closed and the handler switches to the next file in
* the rotating set. A value of zero means that files can grow
@@ -252,16 +288,10 @@ public class FileHandler
public FileHandler()
throws IOException, SecurityException
{
- this(/* pattern: use configiguration */ null,
-
- LogManager.getIntProperty("java.util.logging.FileHandler.limit",
- /* default */ 0),
-
- LogManager.getIntProperty("java.util.logging.FileHandler.count",
- /* default */ 1),
-
- LogManager.getBooleanProperty("java.util.logging.FileHandler.append",
- /* default */ false));
+ this(LogManager.getLogManager().getProperty(PATTERN_KEY),
+ LogManager.getIntProperty(LIMIT_KEY, DEFAULT_LIMIT),
+ LogManager.getIntProperty(COUNT_KEY, DEFAULT_COUNT),
+ LogManager.getBooleanProperty(APPEND_KEY, DEFAULT_APPEND));
}
@@ -269,10 +299,7 @@ public class FileHandler
public FileHandler(String pattern)
throws IOException, SecurityException
{
- this(pattern,
- /* limit */ 0,
- /* count */ 1,
- /* append */ false);
+ this(pattern, DEFAULT_LIMIT, DEFAULT_COUNT, DEFAULT_APPEND);
}
@@ -280,10 +307,7 @@ public class FileHandler
public FileHandler(String pattern, boolean append)
throws IOException, SecurityException
{
- this(pattern,
- /* limit */ 0,
- /* count */ 1,
- append);
+ this(pattern, DEFAULT_LIMIT, DEFAULT_COUNT, append);
}
@@ -292,9 +316,7 @@ public class FileHandler
throws IOException, SecurityException
{
this(pattern, limit, count,
- LogManager.getBooleanProperty(
- "java.util.logging.FileHandler.append",
- /* default */ false));
+ LogManager.getBooleanProperty(APPEND_KEY, DEFAULT_APPEND));
}
@@ -350,7 +372,7 @@ public class FileHandler
throws IOException, SecurityException
{
super(/* output stream, created below */ null,
- "java.util.logging.FileHandler",
+ PROPERTY_PREFIX,
/* default level */ Level.ALL,
/* formatter */ null,
/* default formatter */ XMLFormatter.class);
@@ -358,14 +380,14 @@ public class FileHandler
if ((limit <0) || (count < 1))
throw new IllegalArgumentException();
- this.pattern = pattern;
+ this.pattern = pattern != null ? pattern : DEFAULT_PATTERN;
this.limit = limit;
this.count = count;
this.append = append;
this.written = 0;
this.logFiles = new LinkedList ();
- setOutputStream (createFileStream (pattern, limit, count, append,
+ setOutputStream (createFileStream (this.pattern, limit, count, append,
/* generation */ 0));
}
@@ -389,10 +411,9 @@ public class FileHandler
* LogManager configuration property.
*/
if (pattern == null)
- pattern = LogManager.getLogManager().getProperty(
- "java.util.logging.FileHandler.pattern");
+ pattern = LogManager.getLogManager().getProperty(PATTERN_KEY);
if (pattern == null)
- pattern = "%h/java%u.log";
+ pattern = DEFAULT_PATTERN;
if (count > 1 && !has (pattern, 'g'))
pattern = pattern + ".%g";
diff --git a/java/util/logging/LogManager.java b/java/util/logging/LogManager.java
index e2604815b..ab84e7ac9 100644
--- a/java/util/logging/LogManager.java
+++ b/java/util/logging/LogManager.java
@@ -836,11 +836,11 @@ public class LogManager
}
catch (ClassNotFoundException e)
{
- warn(property, className, "class not found");
+ warn(property, className, "class not found", e);
}
catch (IllegalAccessException e)
{
- warn(property, className, "illegal access");
+ warn(property, className, "illegal access", e);
}
catch (InstantiationException e)
{
@@ -848,7 +848,7 @@ public class LogManager
}
catch (java.lang.LinkageError e)
{
- warn(property, className, "linkage error");
+ warn(property, className, "linkage error", e);
}
return null;
diff --git a/java/util/logging/Logger.java b/java/util/logging/Logger.java
index 567020ef7..46588e542 100644
--- a/java/util/logging/Logger.java
+++ b/java/util/logging/Logger.java
@@ -41,6 +41,8 @@ package java.util.logging;
import java.util.List;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
/**
* A Logger is used for logging information about events. Usually, there
@@ -76,7 +78,20 @@ public class Logger
* products are supposed to create and use their own Loggers, so
* they can be controlled individually.
*/
- public static final Logger global = getLogger("global");
+ public static final Logger global;
+
+ static
+ {
+ // Our class might be initialized from an unprivileged context
+ global = (Logger) AccessController.doPrivileged
+ (new PrivilegedAction()
+ {
+ public Object run()
+ {
+ return getLogger("global");
+ }
+ });
+ }
/**
@@ -1194,7 +1209,7 @@ public class Logger
/**
* Reset and close handlers attached to this logger. This function is package
- * private because it must only be avaiable to the LogManager.
+ * private because it must only be available to the LogManager.
*/
void resetLogger()
{
diff --git a/javax/accessibility/AccessibleContext.java b/javax/accessibility/AccessibleContext.java
index 972f4feae..ee3a5287b 100644
--- a/javax/accessibility/AccessibleContext.java
+++ b/javax/accessibility/AccessibleContext.java
@@ -496,7 +496,7 @@ public abstract class AccessibleContext
}
/**
- * Get any supported accessible compoent. The default implementation returns
+ * Get any supported accessible component. The default implementation returns
* null.
*
* @return the supported component, or null
diff --git a/javax/imageio/stream/ImageInputStreamImpl.java b/javax/imageio/stream/ImageInputStreamImpl.java
index c1a5dd404..71eec41a9 100644
--- a/javax/imageio/stream/ImageInputStreamImpl.java
+++ b/javax/imageio/stream/ImageInputStreamImpl.java
@@ -81,7 +81,8 @@ public abstract class ImageInputStreamImpl implements ImageInputStream
protected void finalize()
throws Throwable
{
- close();
+ if (!closed)
+ close();
}
public void flush()
@@ -154,38 +155,43 @@ public abstract class ImageInputStreamImpl implements ImageInputStream
}
catch (IOException e)
{
- // Ignored.
+ throw new RuntimeException(e);
}
}
public abstract int read()
throws IOException;
+ public abstract int read(byte[] data, int offset, int len)
+ throws IOException;
+
public int read(byte[] data)
throws IOException
{
return read(data, 0, data.length);
}
- public abstract int read(byte[] data, int offset, int len)
- throws IOException;
-
public int readBit()
throws IOException
{
checkClosed();
- // Calc new bit offset here, readByte resets it.
+ // Calculate new bit offset here as readByte clears it.
int newOffset = (bitOffset + 1) & 0x7;
+ // Clears bitOffset.
byte data = readByte();
-
- if (bitOffset != 0)
+
+ // If newOffset is 0 it means we just read the 8th bit in a byte
+ // and therefore we want to advance to the next byte. Otherwise
+ // we want to roll back the stream one byte so that future readBit
+ // calls read bits from the same current byte.
+ if (newOffset != 0)
{
- seek(getStreamPosition() - 1);
- data = (byte) (data >> (8 - newOffset));
+ seek(getStreamPosition() - 1);
+ data = (byte) (data >> (8 - newOffset));
}
-
+
bitOffset = newOffset;
return data & 0x1;
}
@@ -198,17 +204,13 @@ public abstract class ImageInputStreamImpl implements ImageInputStream
if (numBits < 0 || numBits > 64)
throw new IllegalArgumentException();
- if (numBits == 0)
- return 0L;
-
long bits = 0L;
-
+
for (int i = 0; i < numBits; i++)
{
bits <<= 1;
bits |= readBit();
}
-
return bits;
}
@@ -216,12 +218,15 @@ public abstract class ImageInputStreamImpl implements ImageInputStream
throws IOException
{
byte data = readByte();
+
return data != 0;
}
public byte readByte()
throws IOException
{
+ checkClosed();
+
int data = read();
if (data == -1)
@@ -233,10 +238,7 @@ public abstract class ImageInputStreamImpl implements ImageInputStream
public void readBytes(IIOByteBuffer buffer, int len)
throws IOException
{
- int result = read(buffer.getData(), buffer.getOffset(), len);
-
- if (result == -1 || result < len)
- throw new EOFException();
+ readFullyPrivate(buffer.getData(), buffer.getOffset(), len);
buffer.setLength(len);
}
@@ -250,13 +252,13 @@ public abstract class ImageInputStreamImpl implements ImageInputStream
public double readDouble()
throws IOException
{
- return (double) readLong();
+ return Double.longBitsToDouble(readLong());
}
public float readFloat()
throws IOException
{
- return (float) readInt();
+ return Float.intBitsToFloat(readInt());
}
public void readFully(byte[] data)
@@ -268,8 +270,7 @@ public abstract class ImageInputStreamImpl implements ImageInputStream
public void readFully(byte[] data, int offset, int len)
throws IOException
{
- for (int i = 0; i < len; ++i)
- data[offset + i] = readByte();
+ readFullyPrivate(data, offset, len);
}
public void readFully(char[] data, int offset, int len)
@@ -317,23 +318,20 @@ public abstract class ImageInputStreamImpl implements ImageInputStream
public int readInt()
throws IOException
{
- int result = read(buffer, 0, 4);
+ readFullyPrivate(buffer, 0, 4);
- if (result == -1)
- throw new EOFException();
-
if (getByteOrder() == ByteOrder.LITTLE_ENDIAN)
- {
- return ((buffer[0] & 0xff)
- + (buffer[1] << 8)
- + (buffer[2] << 16)
- + (buffer[3] << 24));
- }
+ return (int)
+ (((int) (buffer[0] & 0xff) << 0)
+ | ((int) (buffer[1] & 0xff) << 8)
+ | ((int) (buffer[2] & 0xff) << 16)
+ | ((int) (buffer[3] & 0xff) << 24));
- return ((buffer[4] << 24)
- + (buffer[3] << 16)
- + (buffer[2] << 8)
- + (buffer[1] & 0xff));
+ return (int)
+ (((int) (buffer[0] & 0xff) << 24)
+ + ((int) (buffer[1] & 0xff) << 16)
+ + ((int) (buffer[2] & 0xff) << 8)
+ + ((int) (buffer[3] & 0xff) << 0));
}
public String readLine()
@@ -345,94 +343,101 @@ public abstract class ImageInputStreamImpl implements ImageInputStream
boolean eol = false;
StringBuffer buffer = new StringBuffer();
- while (!eol && (c = read()) != -1)
+ c = read();
+ if (c == -1)
+ return null;
+
+ while (!eol)
{
switch(c)
{
case '\r':
- // Consume following \n'
- long oldPosition = getStreamPosition();
- if (read() != '\n')
- seek(oldPosition);
+ // Check for following '\n'.
+ long oldPosition = getStreamPosition();
+ c = read();
+ if (c == -1 || c == '\n')
+ eol = true;
+ else
+ {
+ seek(oldPosition);
+ eol = true;
+ }
+ continue;
+
case '\n':
eol = true;
- break;
+ continue;
+
default:
buffer.append((char) c);
break;
}
+ c = read();
+ if (c == -1)
+ eol = true;
}
- if (c == -1 && buffer.length() == 0)
- return null;
-
return buffer.toString();
}
public long readLong()
throws IOException
{
- int result = read(buffer, 0, 8);
+ readFullyPrivate(buffer, 0, 8);
- if (result == -1)
- throw new EOFException();
-
if (getByteOrder() == ByteOrder.LITTLE_ENDIAN)
- {
- return ((buffer[0] & 0xff)
- + (((buffer[1] & 0xff)) << 8)
- + (((buffer[2] & 0xff)) << 16)
- + (((buffer[3] & 0xffL)) << 24)
- + (((buffer[4] & 0xffL)) << 32)
- + (((buffer[5] & 0xffL)) << 40)
- + (((buffer[6] & 0xffL)) << 48)
- + (((long) buffer[7]) << 56));
- }
-
- return ((((long) buffer[7]) << 56)
- + ((buffer[6] & 0xffL) << 48)
- + ((buffer[5] & 0xffL) << 40)
- + ((buffer[4] & 0xffL) << 32)
- + ((buffer[3] & 0xffL) << 24)
- + ((buffer[2] & 0xff) << 16)
- + ((buffer[1] & 0xff) << 8)
- + (buffer[0] & 0xff));
+ return (long)
+ (((long) (buffer[0] & 0xff) << 0)
+ | ((long) (buffer[1] & 0xff) << 8)
+ | ((long) (buffer[2] & 0xff) << 16)
+ | ((long) (buffer[3] & 0xff) << 24)
+ | ((long) (buffer[4] & 0xff) << 32)
+ | ((long) (buffer[5] & 0xff) << 40)
+ | ((long) (buffer[6] & 0xff) << 48)
+ | ((long) (buffer[7] & 0xff) << 56));
+
+ return (long)
+ (((long) (buffer[0] & 0xff) << 56)
+ | ((long) (buffer[1] & 0xff) << 48)
+ | ((long) (buffer[2] & 0xff) << 40)
+ | ((long) (buffer[3] & 0xff) << 32)
+ | ((long) (buffer[4] & 0xff) << 24)
+ | ((long) (buffer[5] & 0xff) << 16)
+ | ((long) (buffer[6] & 0xff) << 8)
+ | ((long) (buffer[7] & 0xff) << 0));
}
public short readShort()
throws IOException
{
- int result = read(buffer, 0, 2);
+ readFullyPrivate(buffer, 0, 2);
- if (result == -1)
- throw new EOFException();
-
if (getByteOrder() == ByteOrder.LITTLE_ENDIAN)
- {
- return (short) ((buffer[0] & 0xff)
- + (buffer[1] << 8));
- }
+ return (short)
+ (((short) (buffer[0] & 0xff) << 0)
+ | ((short) (buffer[1] & 0xff) << 8));
- return (short) ((buffer[0] << 8)
- + (buffer[1] & 0xff));
+ return (short)
+ (((short) (buffer[0] & 0xff) << 8)
+ | ((short) (buffer[1] & 0xff) << 0));
}
public int readUnsignedByte()
throws IOException
{
- return readByte() & 0xff;
+ return (int) readByte() & 0xff;
}
public long readUnsignedInt()
throws IOException
{
- return readInt() & 0xffffffff;
+ return (long) readInt() & 0xffffffffL;
}
public int readUnsignedShort()
throws IOException
{
- return readShort() & 0xffff;
+ return (int) readShort() & 0xffff;
}
public String readUTF()
@@ -442,7 +447,8 @@ public abstract class ImageInputStreamImpl implements ImageInputStream
String data;
ByteOrder old = getByteOrder();
- setByteOrder(ByteOrder.BIG_ENDIAN); // Strings are always big endian.
+ // Strings are always big endian.
+ setByteOrder(ByteOrder.BIG_ENDIAN);
try
{
@@ -483,7 +489,7 @@ public abstract class ImageInputStreamImpl implements ImageInputStream
checkClosed();
if (bitOffset < 0 || bitOffset > 7)
- throw new IllegalArgumentException();
+ throw new IllegalArgumentException("bitOffset not between 0 and 7 inclusive");
this.bitOffset = bitOffset;
}
@@ -512,4 +518,23 @@ public abstract class ImageInputStreamImpl implements ImageInputStream
bitOffset = 0;
return num;
}
+
+ private void readFullyPrivate (byte[] buf, int offset, int len) throws IOException
+ {
+ checkClosed();
+
+ if (len < 0)
+ throw new IndexOutOfBoundsException("Negative length: " + len);
+
+ while (len > 0)
+ {
+ // read will block until some data is available.
+ int numread = read (buf, offset, len);
+ if (numread < 0)
+ throw new EOFException ();
+ len -= numread;
+ offset += numread;
+ }
+ bitOffset = 0;
+ }
}
diff --git a/javax/imageio/stream/MemoryCacheImageInputStream.java b/javax/imageio/stream/MemoryCacheImageInputStream.java
index 935408c9a..da8a958bb 100644
--- a/javax/imageio/stream/MemoryCacheImageInputStream.java
+++ b/javax/imageio/stream/MemoryCacheImageInputStream.java
@@ -38,10 +38,11 @@ exception statement from your version. */
package javax.imageio.stream;
-import gnu.classpath.NotImplementedException;
-
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
/**
* @author Michael Koch (konqueror@gmx.de)
@@ -49,10 +50,15 @@ import java.io.InputStream;
public class MemoryCacheImageInputStream extends ImageInputStreamImpl
{
private InputStream stream;
+ private BufferedInputStream buffer;
+
+ private int READLIMIT = 2048;
public MemoryCacheImageInputStream(InputStream stream)
{
this.stream = stream;
+ buffer = new BufferedInputStream(stream);
+ buffer.mark(READLIMIT);
}
public void close()
@@ -63,10 +69,13 @@ public class MemoryCacheImageInputStream extends ImageInputStreamImpl
}
public void flushBefore(long position)
- throws IOException, NotImplementedException
+ throws IOException
{
- // FIXME: Implement me.
- throw new Error("not implemented");
+ long prevFlushedPosition = getFlushedPosition();
+ super.flushBefore(position);
+ buffer.reset();
+ buffer.skip(getFlushedPosition() - prevFlushedPosition);
+ buffer.mark(READLIMIT);
}
public boolean isCached()
@@ -88,13 +97,33 @@ public class MemoryCacheImageInputStream extends ImageInputStreamImpl
throws IOException
{
setBitOffset(0);
- return stream.read();
+ int retval = buffer.read();
+
+ if (retval != -1)
+ streamPos++;
+
+ return retval;
}
public int read(byte[] data, int offset, int len)
throws IOException
{
setBitOffset(0);
- return stream.read(data, offset, len);
+ int retval = buffer.read(data, offset, len);
+
+ if (retval != -1)
+ {
+ streamPos += retval;
+ }
+
+ return retval;
+ }
+
+ public void seek(long position)
+ throws IOException
+ {
+ super.seek(position);
+ buffer.reset();
+ buffer.skip(position - getFlushedPosition());
}
}
diff --git a/javax/naming/CompositeName.java b/javax/naming/CompositeName.java
index 6f3466ca2..322f63279 100644
--- a/javax/naming/CompositeName.java
+++ b/javax/naming/CompositeName.java
@@ -47,11 +47,18 @@ import java.util.NoSuchElementException;
import java.util.Vector;
/**
+ * Represents names that may span over several namespaces. For instance,
+ * the composite name http://www.gnu.org/software/classpath/index.html spans
+ * over three namespaces (the protocol http, the web server location
+ * (www.gnu.org) and the index.html location on the server).
+ *
* @author Tom Tromey (tromey@redhat.com)
*/
public class CompositeName implements Name, Cloneable, Serializable
{
private static final long serialVersionUID = 1667768148915813118L;
+
+ private transient Vector elts;
public CompositeName ()
{
@@ -331,6 +338,4 @@ public class CompositeName implements Name, Cloneable, Serializable
for (int i = 0; i < elts.size(); i++)
s.writeObject(elts.get(i));
}
-
- private transient Vector elts;
}
diff --git a/javax/naming/CompoundName.java b/javax/naming/CompoundName.java
index b23736fa7..556edfc33 100644
--- a/javax/naming/CompoundName.java
+++ b/javax/naming/CompoundName.java
@@ -48,6 +48,10 @@ import java.util.Properties;
import java.util.Vector;
/**
+ * Represents hierarchical names from the single namespace. For instance,
+ * the path /home/audriusa/classpath/file.txt is the compound name, using
+ * the filesystem namespace.
+ *
* @author Tom Tromey (tromey@redhat.com)
* @date May 16, 2001
*
diff --git a/javax/naming/Context.java b/javax/naming/Context.java
index 9df82c684..46b540304 100644
--- a/javax/naming/Context.java
+++ b/javax/naming/Context.java
@@ -1,5 +1,5 @@
-/* Context.java --
- Copyright (C) 2000 Free Software Foundation, Inc.
+/* Context.java -- A naming context
+ Copyright (C) 2000, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -40,121 +40,453 @@ package javax.naming;
import java.util.Hashtable;
+import javax.naming.directory.InvalidAttributesException;
+
public interface Context
{
- // Property with name of the inital context factory to use
- String INITIAL_CONTEXT_FACTORY
- = "java.naming.factory.initial";
-
- // Property with colon-separated list of object factories to use.
- String OBJECT_FACTORIES
- = "java.naming.factory.object";
-
- // Property with colon-separated list of state factories to use.
- String STATE_FACTORIES
- = "java.naming.factory.state";
-
- // Property with colon-separated list of package prefixes to use.
- String URL_PKG_PREFIXES
- = "java.naming.factory.url.pkgs";
-
- // Property with URL specifying configuration for the service
- // provider to use.
- String PROVIDER_URL
- = "java.naming.provider.url";
+ /**
+ * Property with name of the inital context factory to use
+ */
+ String INITIAL_CONTEXT_FACTORY = "java.naming.factory.initial";
+
+ /**
+ * Property with colon-separated list of object factories to use.
+ */
+ String OBJECT_FACTORIES = "java.naming.factory.object";
+
+ /**
+ * Property with colon-separated list of state factories to use.
+ */
+ String STATE_FACTORIES = "java.naming.factory.state";
+
+ /**
+ * Property with colon-separated list of package prefixes to use.
+ */
+ String URL_PKG_PREFIXES = "java.naming.factory.url.pkgs";
+
+ /**
+ * Property with URL specifying configuration for the service provider to use.
+ */
+ String PROVIDER_URL = "java.naming.provider.url";
+
+ /**
+ * Property with the DNS host and domain names to use.
+ */
+ String DNS_URL = "java.naming.dns.url";
+
+ /**
+ * Property with the authoritativeness of the service requested.
+ */
+ String AUTHORITATIVE = "java.naming.authoritative";
+
+ /**
+ * Property with the batch size to use when returning data via the service's
+ * protocol.
+ */
+ String BATCHSIZE = "java.naming.batchsize";
+
+ /**
+ * Property defining how referrals encountered by the service provider are to
+ * be processed.
+ */
+ String REFERRAL = "java.naming.referral";
+
+ /**
+ * Property specifying the security protocol to use.
+ */
+ String SECURITY_PROTOCOL = "java.naming.security.protocol";
+
+ /**
+ * Property specifying the security level to use.
+ */
+ String SECURITY_AUTHENTICATION = "java.naming.security.authentication";
+
+ /**
+ * Property for the identity of the principal for authenticating the caller to
+ * the service.
+ */
+ String SECURITY_PRINCIPAL = "java.naming.security.principal";
+
+ /**
+ * Property specifying the credentials of the principal for authenticating the
+ * caller to the service.
+ */
+ String SECURITY_CREDENTIALS = "java.naming.security.credentials";
+
+ /**
+ * Property for specifying the preferred language to use with the service.
+ */
+ String LANGUAGE = "java.naming.language";
+
+ /**
+ * Property for the initial context constructor to use when searching for
+ * other properties.
+ */
+ String APPLET = "java.naming.applet";
+
+ /**
+ * Give the specified name for the specified object. The passed name must not
+ * be already bound to some other object.
+ *
+ * @param name the name that will be given to the object (in the scope of this
+ * context).
+ * @param obj the object being named.
+ * @throws NameAlreadyBoundException if this name is already used to name some
+ * object.
+ * @throws InvalidAttributesException if the object does not supply all
+ * required attributes.
+ * @throws NamingException if the naming operation has failed due other
+ * reasons.
+ */
+ void bind(Name name, Object obj) throws NamingException;
+
+ /**
+ * Give the specified name for the specified object. The passed name must not
+ * be already bound to some other object.
+ *
+ * @param name the name that will be given to the object (in the scope of this
+ * context).
+ * @param obj the object being named.
+ * @throws NameAlreadyBoundException if this name is already used to name some
+ * object.
+ * @throws InvalidAttributesException if the object does not supply all
+ * required attributes.
+ * @throws NamingException if the naming operation has failed due other
+ * reasons.
+ */
+ void bind(String name, Object obj) throws NamingException;
+
+ /**
+ * Gets the previously named object by name. If the passed name is empty, the
+ * method should return a cloned instance of this naming context.
+ *
+ * @param name the name of the object being searched in this context
+ * @return the named object
+ * @throws NamingException if the naming fails.
+ */
+ Object lookup(Name name) throws NamingException;
+
+ /**
+ * Gets the previously named object by name. If the passed name is empty, the
+ * method should return a cloned instance of this naming context.
+ *
+ * @param name the name of the object being searched in this context
+ * @return the named object
+ * @throws NamingException if the naming fails.
+ */
+ Object lookup(String name) throws NamingException;
+
+ /**
+ * Give the specified name for the specified object. Unlike bind, this method
+ * silently replaces the existing binding for this name, if one exists.
+ *
+ * @param name the name that will be given to the object (in the scope of this
+ * context).
+ * @param obj the object being named.
+ * @throws InvalidAttributesException if the object does not supply all
+ * required attributes.
+ * @throws NamingException if the naming operation has failed due other
+ * reasons.
+ */
+ void rebind(Name name, Object obj) throws NamingException;
+
+ /**
+ * Give the specified name for the specified object. Unlike bind, this method
+ * silently replaces the existing binding for this name, if one exists.
+ *
+ * @param name the name that will be given to the object (in the scope of this
+ * context).
+ * @param obj the object being named.
+ * @throws InvalidAttributesException if the object does not supply all
+ * required attributes.
+ * @throws NamingException if the naming operation has failed due other
+ * reasons.
+ */
+ void rebind(String name, Object obj) throws NamingException;
+
+ /**
+ * Removes the name - object mapping from the current context. This method
+ * returns without action if the name is not bound to an object in the
+ * terminal context, but throws {@link NameNotFoundException} if one of the
+ * intermadiate contexts does not exist.
+ *
+ * @param name the name to be removed
+ * @throws NameNotFoundException if one of the intermediate naming contexts
+ * does not exist. Will not be thrown if just the terminal binding
+ * is missing.
+ * @throws NamingException if the naming operation has failed due other
+ * reasons.
+ */
+ void unbind(Name name) throws NamingException;
+
+ /**
+ * Removes the name - object mapping from the current context. This method
+ * returns without action if the name is not bound to an object in the
+ * terminal context, but throws {@link NameNotFoundException} if one of the
+ * intermadiate contexts does not exist.
+ *
+ * @param name the name to be removed
+ * @throws NameNotFoundException if one of the intermediate naming contexts
+ * does not exist. Will not be thrown if just the terminal binding
+ * is missing.
+ * @throws NamingException if the naming operation has failed due other
+ * reasons.
+ */
+ void unbind(String name) throws NamingException;
+
+ /**
+ * Renames the existing binding, removing the existing and giving the new name
+ * for the same object.
+ *
+ * @param oldName the existing name of the known object
+ * @param newName the new name of the same object
+ * @throws NameNotFoundException if the oldName is unknown for this context
+ * @throws NamingException if the naming operation has failed due other
+ * reasons.
+ */
+ void rename(Name oldName, Name newName) throws NamingException;
+
+ /**
+ * Renames the existing binding, removing the existing and giving the new name
+ * for the same object.
+ *
+ * @param oldName the existing name of the known object
+ * @param newName the new name of the same object
+ * @throws NameNotFoundException if the oldName is unknown for this context
+ * @throws NamingException if the naming operation has failed due other
+ * reasons.
+ */
+ void rename(String oldName, String newName) throws NamingException;
+
+ /**
+ * Creates and returns the enumeration over the name bindings that are present
+ * the given subcontext. The enumeration elements have the type of
+ * {@link NameClassPair}, providing also information about the class of the
+ * bound object. The behaviour in the case if the bindings are added or
+ * removed later is not defined. The contents of the subcontexts are not
+ * included.
+ *
+ * @param name the name of the subcontext
+ * @return the enumeration over the names, known for the given subcontext.
+ * @throws NamingException
+ */
+ NamingEnumeration list(Name name) throws NamingException;
+
+ /**
+ * Creates and returns the enumeration over the name bindings that are present
+ * the given subcontext. The enumeration elements have the type of
+ * {@link NameClassPair}, providing also information about the class of the
+ * bound object. The behaviour in the case if the bindings are added or
+ * removed later is not defined. The contents of the subcontexts are not
+ * included.
+ *
+ * @param name the name of the subcontext
+ * @return the enumeration over the names, known for the given subcontext.
+ * @throws NamingException
+ */
+ NamingEnumeration list(String name) throws NamingException;
+
+ /**
+ * Creates and returns the enumeration over the name - object bindings that
+ * are present the given subcontext. The enumeration elements have the type of
+ * {@link Binding}, providing also information about the class of the bound
+ * object. The behaviour in the case if the bindings are added or removed
+ * later is not defined. The contents of the subcontexts are not included.
+ *
+ * @param name the name of the subcontext
+ * @return the enumeration over the names, known for the given subcontext.
+ * @throws NamingException
+ */
+ NamingEnumeration listBindings(Name name) throws NamingException;
+
+ /**
+ * Creates and returns the enumeration over the name - object bindings that
+ * are present the given subcontext. The enumeration elements have the type of
+ * {@link Binding}, providing also information about the class of the bound
+ * object. The behaviour in the case if the bindings are added or removed
+ * later is not defined. The contents of the subcontexts are not included.
+ *
+ * @param name the name of the subcontext
+ * @return the enumeration over the names, known for the given subcontext.
+ * @throws NamingException
+ */
+ NamingEnumeration listBindings(String name) throws NamingException;
+
+ /**
+ * Creates the new naming subcontext and binds it to the current (this)
+ * context.
+ *
+ * @param name the name of the new context being created
+ * @return the newly created context, bound to the instance of the context on
+ * that the method has been called
+ * @throws NameAlreadyBoundException if this name is already bound
+ * @throws InvalidAttributesException if the creation of the new context
+ * requires the missing mandatory attributes
+ * @throws NamingException
+ */
+ Context createSubcontext(Name name) throws NamingException;
+
+ /**
+ * Creates the new naming subcontext and binds it to the current (this)
+ * context.
+ *
+ * @param name the name of the new context being created
+ * @return the newly created context, bound to the instance of the context on
+ * that the method has been called
+ * @throws NameAlreadyBoundException if this name is already bound
+ * @throws InvalidAttributesException if the creation of the new context
+ * requires the missing mandatory attributes
+ * @throws NamingException
+ */
+ Context createSubcontext(String name) throws NamingException;
+
+ /**
+ * Removes the naming subcontext from this naming context. Returns without
+ * action if such subcontext does not exist. The context being destroyed must
+ * be empty.
+ *
+ * @param name the name of the subcontext beig removed.
+ * @throws ContextNotEmptyException if the named context is not empty.
+ * @throws NamingException
+ */
+ void destroySubcontext(Name name) throws NamingException;
+
+ /**
+ * Removes the naming subcontext from this naming context. Returns without
+ * action if such subcontext does not exist. The context being destroyed must
+ * be empty.
+ *
+ * @param name the name of the subcontext beig removed.
+ * @throws ContextNotEmptyException if the named context is not empty.
+ * @throws NamingException
+ */
+ void destroySubcontext(String name) throws NamingException;
+
+ /**
+ * Retrieves the named object, not following the link of the terminal atomic
+ * component of the name. If the object, named by the passed name, is not a
+ * link, returns that object itself. The intermediate links, if present, are
+ * followed.
+ *
+ * @param name the name of the object that may be a link, leading to another
+ * object.
+ * @return the named object, not following the terminal link (if present).
+ * @throws NamingException
+ */
+ Object lookupLink(Name name) throws NamingException;
+
+ /**
+ * Retrieves the named object, not following the link of the terminal atomic
+ * component of the name. If the object, named by the passed name, is not a
+ * link, returns that object itself. The intermediate links, if present, are
+ * followed.
+ *
+ * @param name the name of the object that may be a link, leading to another
+ * object.
+ * @return the named object, not following the terminal link (if present).
+ * @throws NamingException
+ */
+ Object lookupLink(String name) throws NamingException;
- // Property with the DNS host and domain names to use.
- String DNS_URL
- = "java.naming.dns.url";
+ /**
+ * Obtains the name parser for parsing the names of the given naming
+ * subcontext.
+ *
+ * @param name the name of the subcontext for that the parser must be obtained
+ * @return the parser to parse the names of that context
+ * @throws NamingException
+ */
+ NameParser getNameParser(Name name) throws NamingException;
+
+ /**
+ * Obtains the name parser for parsing the names of the given naming
+ * subcontext.
+ *
+ * @param name the name of the subcontext for that the parser must be obtained
+ * @return the parser to parse the names of that context
+ * @throws NamingException
+ */
+ NameParser getNameParser(String name) throws NamingException;
- // Property with the authoritativeness of the service requested.
- String AUTHORITATIVE
- = "java.naming.authoritative";
+ /**
+ * Composes the name of this context together with another name, related to
+ * this context.
+ *
+ * @param name a name, defined in the scope of this context
+ * @param prefix a name of this context itself, defined in the scope of some
+ * ancestor
+ * @return the name of the same object as named by the first parameter, but
+ * related to the context of the specified ancestor.
+ * @throws NamingException
+ */
+ Name composeName(Name name, Name prefix) throws NamingException;
+
+ /**
+ * Composes the name of this context together with another name, related to
+ * this context.
+ *
+ * @param name a name, defined in the scope of this context
+ * @param prefix a name of this context itself, defined in the scope of some
+ * ancestor
+ * @return the name of the same object as named by the first parameter, but
+ * related to the context of the specified ancestor.
+ * @throws NamingException
+ */
+ String composeName(String name, String prefix) throws NamingException;
- // Property with the batch size to use when returning data via the
- // service's protocol.
- String BATCHSIZE
- = "java.naming.batchsize";
+ /**
+ * Add new environment property to the environment of this context. Both name
+ * and value of the new property must not be null. If the property is already
+ * defined, is current value is replaced by the propVal.
+ *
+ * @param propName the name of the new property
+ * @param propVal the value of the new property
+ * @return the previous value of this property or null if the property has not
+ * been previously defined
+ * @throws NamingException
+ */
+ Object addToEnvironment(String propName, Object propVal)
+ throws NamingException;
- // Property defining how referrals encountered by the service
- // provider are to be processed.
- String REFERRAL
- = "java.naming.referral";
-
- // Property specifying the security protocol to use.
- String SECURITY_PROTOCOL
- = "java.naming.security.protocol";
-
- // Property specifying the security level to use.
- String SECURITY_AUTHENTICATION
- = "java.naming.security.authentication";
-
- // Property for the identity of the principal for authenticating
- // the caller to the service.
- String SECURITY_PRINCIPAL
- = "java.naming.security.principal";
-
- // Property specifying the credentials of the principal for
- // authenticating the caller to the service.
- String SECURITY_CREDENTIALS
- = "java.naming.security.credentials";
-
- // Property for specifying the preferred language to use with the
- // service.
- String LANGUAGE
- = "java.naming.language";
-
- // Property for the initial context constructor to use when searching
- // for other properties.
- String APPLET
- = "java.naming.applet";
-
- void bind (Name name, Object obj) throws NamingException;
- void bind (String name, Object obj) throws NamingException;
-
- Object lookup (Name name) throws NamingException;
- Object lookup (String name) throws NamingException;
-
- void rebind (Name name, Object obj) throws NamingException;
- void rebind (String name, Object obj) throws NamingException;
-
- void unbind (Name name) throws NamingException;
- void unbind (String name) throws NamingException;
-
- void rename (Name oldName, Name newName) throws NamingException;
- void rename (String oldName, String newName) throws NamingException;
-
- NamingEnumeration list (Name name) throws NamingException;
- NamingEnumeration list (String name) throws NamingException;
-
- NamingEnumeration listBindings (Name name) throws NamingException;
- NamingEnumeration listBindings (String name) throws NamingException;
-
- void destroySubcontext (Name name) throws NamingException;
- void destroySubcontext (String name) throws NamingException;
-
- Context createSubcontext (Name name) throws NamingException;
- Context createSubcontext (String name) throws NamingException;
-
- Object lookupLink (Name name) throws NamingException;
- Object lookupLink (String name) throws NamingException;
-
- NameParser getNameParser (Name name) throws NamingException;
- NameParser getNameParser (String name) throws NamingException;
-
- Name composeName (Name name, Name prefix) throws NamingException;
- String composeName (String name,
- String prefix) throws NamingException;
-
- Object addToEnvironment (String propName,
- Object propVal) throws NamingException;
-
- Object removeFromEnvironment (String propName) throws NamingException;
-
- Hashtable getEnvironment () throws NamingException;
-
- void close () throws NamingException;
-
- String getNameInNamespace () throws NamingException;
+ /**
+ * Removes the property with the given name from the environment. Returns
+ * without action if this property is not defined.
+ *
+ * @param propName the name of the property being removed.
+ * @return the value of the property that has been removed or null if the
+ * property was not defined.
+ * @throws NamingException
+ */
+ Object removeFromEnvironment(String propName) throws NamingException;
+
+ /**
+ * Returns the environment, associated with this naming context. The returned
+ * table should never be modified by the caller. Use {@link #addToEnvironment}
+ * and {@link #removeFromEnvironment} to modify the environement, if needed.
+ *
+ * @return the table, representing the environment of this context
+ * @throws NamingException
+ */
+ Hashtable getEnvironment() throws NamingException;
+
+ /**
+ * Releases all resources, associated with this context. The close() method
+ * can be called several times, but after it has been once invoked, it is not
+ * allowed to call any other method of this context,
+ *
+ * @throws NamingException
+ */
+ void close() throws NamingException;
+
+ /**
+ * Returs the full name of this naming context. The returned string is not a
+ * JNDI composite name and should not be passed directly to the methods of the
+ * naming context.
+ *
+ * @return the full name of this naming context, in its own namespace.
+ * @throws OperationNotSupportedException if the naming system, represented by
+ * this context, does not support the notation of the full name.
+ * @throws NamingException
+ */
+ String getNameInNamespace() throws NamingException;
}
-
diff --git a/javax/naming/ContextNotEmptyException.java b/javax/naming/ContextNotEmptyException.java
index acbd46bff..e856341c1 100644
--- a/javax/naming/ContextNotEmptyException.java
+++ b/javax/naming/ContextNotEmptyException.java
@@ -38,7 +38,12 @@ exception statement from your version. */
package javax.naming;
-
+/**
+ * This exception is thrown in response to the attempt to destroy the non
+ * empty context. Only empty contexts (without bindings) can be destroyed.
+ *
+ * @see Context#destroySubcontext
+ */
public class ContextNotEmptyException extends NamingException
{
private static final long serialVersionUID = 1090963683348219877L;
diff --git a/javax/naming/InitialContext.java b/javax/naming/InitialContext.java
index 1a9ee5a27..d4a9587f2 100644
--- a/javax/naming/InitialContext.java
+++ b/javax/naming/InitialContext.java
@@ -1,5 +1,5 @@
-/* InitialContext.java --
- Copyright (C) 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
+/* InitialContext.java -- Initial naming context.
+ Copyright (C) 2000, 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -43,170 +43,291 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
+import java.util.HashSet;
import java.util.Hashtable;
import java.util.Properties;
import javax.naming.spi.NamingManager;
+/**
+ * The starting context for performing naming operations. All naming operations
+ * are performed in the scope of some context. The initial context is the
+ * starting point for the name resolution.
+ */
public class InitialContext implements Context
{
+ /**
+ * Contains the default initial context. This value is returned by
+ * {@link NamingManager#getInitialContext}. It is set by this method
+ * when calling it first time. The subsequent calls return the value of
+ * this field.
+ */
protected Context defaultInitCtx;
+
+ /**
+ * Indicates if the initial context was obtained by calling
+ * {@link NamingManager#getInitialContext}.
+ */
protected boolean gotDefault = false;
+
+ /**
+ * The environment, associated with this initial context.
+ */
protected Hashtable myProps;
- public InitialContext (Hashtable environment)
- throws NamingException
+ /**
+ * The list of the properties, to that the second alternative value must
+ * be appended after the colon to the first possible value. Used in
+ * {@link #merge(Hashtable, Hashtable)}
+ */
+ static final HashSet colon_list;
+ static
+ {
+ colon_list = new HashSet();
+ colon_list.add(Context.OBJECT_FACTORIES);
+ colon_list.add(Context.URL_PKG_PREFIXES);
+ colon_list.add(Context.STATE_FACTORIES);
+ };
+
+ /**
+ * The properties that are searched in the agreed places in the
+ * {@link #init(Hashtable)} method.
+ */
+ static final String[] use_properties =
+ {
+ Context.DNS_URL,
+ Context.INITIAL_CONTEXT_FACTORY,
+ Context.OBJECT_FACTORIES,
+ Context.PROVIDER_URL,
+ Context.STATE_FACTORIES,
+ Context.URL_PKG_PREFIXES,
+ };
+
+
+ /**
+ * Creates the new initial context with the given properties.
+ *
+ * @param environment the properties, used by the initial context being
+ * created.
+ * @throws NamingException
+ */
+ public InitialContext(Hashtable environment) throws NamingException
{
- init (environment);
+ init(environment);
}
- protected InitialContext (boolean lazy)
- throws NamingException
+ /**
+ * Creates the initial context with the possibility to delay its
+ * initialisation.
+ *
+ * @param lazy specified if the initialization should not be performed by this
+ * constructor (true). If the valueis false, it works the same way as
+ * the parameterless constructor.
+ * @throws NamingException
+ */
+ protected InitialContext(boolean lazy) throws NamingException
{
if (! lazy)
- init (null);
+ init(null);
}
- public InitialContext ()
- throws NamingException
+ /**
+ * Creates teh new initial context with no properties. Same as
+ * InitialContext(null).
+ *
+ * @throws NamingException
+ */
+ public InitialContext() throws NamingException
{
- init (null);
+ init(null);
}
- /** @since 1.3 */
- protected void init (Hashtable environment)
- throws NamingException
- {
- // FIXME: Is this enough?
- final String[] properties = {
- Context.DNS_URL,
- Context.INITIAL_CONTEXT_FACTORY,
- Context.OBJECT_FACTORIES,
- Context.PROVIDER_URL,
- Context.STATE_FACTORIES,
- Context.URL_PKG_PREFIXES,
- };
-
- // Create myProps, cloning environment if needed.
+ /**
+ * <p>
+ * Initialises the context, using the properties, specified in the passed
+ * table.
+ * </p>
+ * The missing properties are additionally obtained (in order) from the
+ * following locations:
+ * <ul>
+ * <li>If the passed parameter contains the key Context.APPLET, its value
+ * must be the instance of the {@link Applet}. Then the properties are
+ * requested via {@link Applet#getParameter(String)}.</li>
+ * <li>The value of the system property is used.</li>
+ * <li>The resource "jndi.properties" is requested from the context class
+ * loader of the current thread</li>
+ * <li>The property file "jndi.properties" is read from the location,
+ * specified by the system property "gnu.classpath.home.url".
+ * </ul>
+ * </p>
+ *
+ * @param environment the table of the properties, may be null. The method
+ * modifies the table and stores the reference to it. The caller must
+ * not later reuse this structure for other purposes.
+ * @since 1.3
+ */
+ protected void init(Hashtable environment) throws NamingException
+ {
+ // If is documented that the caller should not modify the environment.
if (environment != null)
- myProps = (Hashtable) environment.clone ();
+ myProps = environment;
else
- myProps = new Hashtable ();
-
- Applet napplet = (Applet) myProps.get (Context.APPLET);
-
- for (int i = properties.length - 1; i >= 0; i--)
+ myProps = new Hashtable();
+
+ Applet napplet = (Applet) myProps.get(Context.APPLET);
+
+ Properties pApplet = null;
+ if (napplet != null)
+ pApplet = new Properties();
+ Properties pSystem = new Properties();
+ Object value;
+
+ for (int i = use_properties.length - 1; i >= 0; i--)
{
- Object o = myProps.get (properties[i]);
-
- if (o == null)
- {
- if (napplet != null)
- o = napplet.getParameter (properties[i]);
- if (o == null)
- o = System.getProperty (properties[i]);
- if (o != null)
- myProps.put (properties[i], o);
- }
+ String key = use_properties[i];
+ if (napplet != null)
+ {
+ value = napplet.getParameter(key);
+ if (value != null)
+ pApplet.put(key, value);
+ }
+
+ value = System.getProperty(key);
+ if (value != null)
+ pSystem.put(key, value);
}
+
+ merge(myProps, pSystem);
+ if (pApplet != null)
+ merge(myProps, pApplet);
try
{
- Enumeration ep = Thread.currentThread().getContextClassLoader().getResources("jndi.naming");
- while (ep.hasMoreElements ())
- {
- URL url = (URL) ep.nextElement ();
- Properties p = new Properties ();
-
- try
- {
- InputStream is = url.openStream ();
- p.load (is);
- is.close ();
- }
- catch (IOException e)
- {
- }
-
- merge (myProps, p);
- }
+ Enumeration ep = Thread.currentThread().
+ getContextClassLoader().getResources("jndi.properties");
+ while (ep.hasMoreElements())
+ {
+ URL url = (URL) ep.nextElement();
+ Properties p = new Properties();
+
+ try
+ {
+ InputStream is = url.openStream();
+ p.load(is);
+ is.close();
+ }
+ catch (IOException e)
+ {
+ // Ignore.
+ }
+
+ merge(myProps, p);
+ }
}
catch (IOException e)
{
+ // Ignore.
}
String home = System.getProperty("gnu.classpath.home.url");
if (home != null)
{
- String url = home + "/jndi.properties";
- Properties p = new Properties ();
-
- try
- {
- InputStream is = new URL(url).openStream();
- p.load (is);
- is.close ();
- }
- catch (IOException e)
- {
- // Ignore.
- }
-
- merge (myProps, p);
+ String url = home + "/jndi.properties";
+ Properties p = new Properties();
+
+ try
+ {
+ InputStream is = new URL(url).openStream();
+ p.load(is);
+ is.close();
+ }
+ catch (IOException e)
+ {
+ // Ignore.
+ }
+
+ merge(myProps, p);
}
}
-
- // FIXME: Is this enough?
- private static final String[] colon_list =
- {
- Context.OBJECT_FACTORIES,
- Context.URL_PKG_PREFIXES,
- Context.STATE_FACTORIES
- };
-
- private static void merge (Hashtable h1, Hashtable h2)
- {
- Enumeration e2 = h2.keys();
+
+ /**
+ * Merge the content of the two tables. If the second table contains the key
+ * that is missing in the first table, this key - value pair is copied to the
+ * first table. If both first and second tables contain the same key AND the
+ * {@link #colon_list} set also contains this key, the value from the second
+ * table is appended to the value from the first table after semicolon, and
+ * the resulted value replaces the value in the first table.
+ *
+ * @param primary the first table to merge. The merged result is also stored
+ * in this table.
+ * @param additional the second table, from where additional values are taken
+ */
+ static void merge (Hashtable primary, Hashtable additional)
+ {
+ Enumeration en = additional.keys();
- while (e2.hasMoreElements())
+ while (en.hasMoreElements())
{
- String key2 = (String) e2.nextElement();
- Object value1 = h1.get(key2);
- if (value1 == null)
- h1.put(key2, h2.get(key2));
- else if (key2.compareTo(colon_list[0]) == 0
- || key2.compareTo(colon_list[1]) == 0
- || key2.compareTo(colon_list[2]) == 0
- || key2.compareTo(colon_list[3]) == 0)
- {
- String value2 = (String) h2.get(key2);
- h1.put(key2, (String) value1 + ":" + value2);
- }
+ String key2 = (String) en.nextElement();
+ Object value1 = primary.get(key2);
+ if (value1 == null)
+ primary.put(key2, additional.get(key2));
+ else if (colon_list.contains(key2))
+ {
+ String value2 = (String) additional.get(key2);
+ primary.put(key2, (String) value1 + ":" + value2);
+ }
}
}
-
- protected Context getDefaultInitCtx () throws NamingException
+
+ /**
+ * Get the default initial context. If {@link #gotDefault} == false, this
+ * method obtains the initial context from the naming manager and sets
+ * gotDefault to true. Otherwise the cached value ({@link #defaultInitCtx} is
+ * returned.
+ *
+ * @return the default initial context
+ * @throws NamingException
+ */
+ protected Context getDefaultInitCtx() throws NamingException
{
if (! gotDefault)
{
- defaultInitCtx = NamingManager.getInitialContext (myProps);
- gotDefault = true;
+ defaultInitCtx = NamingManager.getInitialContext(myProps);
+ gotDefault = true;
}
return defaultInitCtx;
}
-
- protected Context getURLOrDefaultInitCtx (Name name)
- throws NamingException
- {
- if (name.size () > 0)
- return getURLOrDefaultInitCtx (name.get (0));
+ /**
+ * Obtains the context for resolving the given name. If the first component of
+ * the name is the URL string, this method tries to find the corressponding
+ * URL naming context. If it is not an URL string, or the URL context is not
+ * found, the default initial context is returned.
+ *
+ * @param name the name, for that it is required to obtain the context.
+ * @return the context for resolving the name.
+ * @throws NamingException
+ */
+ protected Context getURLOrDefaultInitCtx(Name name) throws NamingException
+ {
+ if (name.size() > 0)
+ return getURLOrDefaultInitCtx(name.get(0));
else
- return getDefaultInitCtx ();
+ return getDefaultInitCtx();
}
- protected Context getURLOrDefaultInitCtx (String name)
- throws NamingException
+ /**
+ * Obtains the context for resolving the given name. If the first component of
+ * the name is the URL string, this method tries to find the corressponding
+ * URL naming context. If it is not an URL string, or the URL context is not
+ * found, the default initial context is returned.
+ *
+ * @param name the name, for that it is required to obtain the context.
+ * @return the context for resolving the name.
+ * @throws NamingException
+ */
+ protected Context getURLOrDefaultInitCtx(String name) throws NamingException
{
String scheme = null;
@@ -214,178 +335,211 @@ public class InitialContext implements Context
return getDefaultInitCtx();
int colon = name.indexOf(':');
int slash = name.indexOf('/');
- if (colon > 0 && (slash == -1 || colon < slash))
+ if (colon > 0 && (slash == - 1 || colon < slash))
scheme = name.substring(0, colon);
- if (scheme != null)
+ if (scheme != null)
{
- Context context =
- NamingManager.getURLContext(scheme, myProps);
- if (context != null)
- return context;
+ Context context = NamingManager.getURLContext(scheme, myProps);
+ if (context != null)
+ return context;
}
-
+
return getDefaultInitCtx();
}
+ /** @inheritDoc */
public void bind (Name name, Object obj) throws NamingException
{
getURLOrDefaultInitCtx (name).bind (name, obj);
}
+ /** @inheritDoc */
public void bind (String name, Object obj) throws NamingException
{
getURLOrDefaultInitCtx (name).bind (name, obj);
}
+ /** @inheritDoc */
public Object lookup (Name name) throws NamingException
{
try
{
- return getURLOrDefaultInitCtx (name).lookup (name);
+ return getURLOrDefaultInitCtx (name).lookup (name);
}
catch (CannotProceedException cpe)
{
- Context ctx = NamingManager.getContinuationContext (cpe);
- return ctx.lookup (cpe.getRemainingName());
+ Context ctx = NamingManager.getContinuationContext (cpe);
+ return ctx.lookup (cpe.getRemainingName());
}
}
+ /** @inheritDoc */
public Object lookup (String name) throws NamingException
{
try
- {
- return getURLOrDefaultInitCtx (name).lookup (name);
- }
+ {
+ return getURLOrDefaultInitCtx (name).lookup (name);
+ }
catch (CannotProceedException cpe)
- {
- Context ctx = NamingManager.getContinuationContext (cpe);
- return ctx.lookup (cpe.getRemainingName());
- }
+ {
+ Context ctx = NamingManager.getContinuationContext (cpe);
+ return ctx.lookup (cpe.getRemainingName());
+ }
}
+ /** @inheritDoc */
public void rebind (Name name, Object obj) throws NamingException
{
getURLOrDefaultInitCtx (name).rebind (name, obj);
}
-
+
+ /** @inheritDoc */
public void rebind (String name, Object obj) throws NamingException
{
getURLOrDefaultInitCtx (name).rebind (name, obj);
}
+ /** @inheritDoc */
public void unbind (Name name) throws NamingException
{
getURLOrDefaultInitCtx (name).unbind (name);
}
+ /** @inheritDoc */
public void unbind (String name) throws NamingException
{
getURLOrDefaultInitCtx (name).unbind (name);
}
+ /** @inheritDoc */
public void rename (Name oldName, Name newName) throws NamingException
{
getURLOrDefaultInitCtx (oldName).rename (oldName, newName);
}
+ /** @inheritDoc */
public void rename (String oldName, String newName) throws NamingException
{
getURLOrDefaultInitCtx (oldName).rename (oldName, newName);
}
+ /** @inheritDoc */
public NamingEnumeration list (Name name) throws NamingException
{
return getURLOrDefaultInitCtx (name).list (name);
}
+ /** @inheritDoc */
public NamingEnumeration list (String name) throws NamingException
{
return getURLOrDefaultInitCtx (name).list (name);
}
+ /** @inheritDoc */
public NamingEnumeration listBindings (Name name) throws NamingException
{
return getURLOrDefaultInitCtx (name).listBindings (name);
}
+ /** @inheritDoc */
public NamingEnumeration listBindings (String name) throws NamingException
{
return getURLOrDefaultInitCtx (name).listBindings (name);
}
+ /** @inheritDoc */
public void destroySubcontext (Name name) throws NamingException
{
getURLOrDefaultInitCtx (name).destroySubcontext (name);
}
+ /** @inheritDoc */
public void destroySubcontext (String name) throws NamingException
{
getURLOrDefaultInitCtx (name).destroySubcontext (name);
}
+ /** @inheritDoc */
public Context createSubcontext (Name name) throws NamingException
{
return getURLOrDefaultInitCtx (name).createSubcontext (name);
}
+ /** @inheritDoc */
public Context createSubcontext (String name) throws NamingException
{
return getURLOrDefaultInitCtx (name).createSubcontext (name);
}
+ /** @inheritDoc */
public Object lookupLink (Name name) throws NamingException
{
return getURLOrDefaultInitCtx (name).lookupLink (name);
}
+ /** @inheritDoc */
public Object lookupLink (String name) throws NamingException
{
return getURLOrDefaultInitCtx (name).lookupLink (name);
}
+ /** @inheritDoc */
public NameParser getNameParser (Name name) throws NamingException
{
return getURLOrDefaultInitCtx (name).getNameParser (name);
}
+ /** @inheritDoc */
public NameParser getNameParser (String name) throws NamingException
{
return getURLOrDefaultInitCtx (name).getNameParser (name);
}
+ /** @inheritDoc */
public Name composeName (Name name, Name prefix) throws NamingException
{
return getURLOrDefaultInitCtx (name).composeName (name, prefix);
}
+ /** @inheritDoc */
public String composeName (String name,
- String prefix) throws NamingException
+ String prefix) throws NamingException
{
return getURLOrDefaultInitCtx (name).composeName (name, prefix);
}
-
+
+ /** @inheritDoc */
public Object addToEnvironment (String propName,
- Object propVal) throws NamingException
+ Object propVal) throws NamingException
{
return myProps.put (propName, propVal);
}
+ /** @inheritDoc */
public Object removeFromEnvironment (String propName) throws NamingException
{
return myProps.remove (propName);
}
+ /** @inheritDoc */
public Hashtable getEnvironment () throws NamingException
{
return myProps;
}
+ /** @inheritDoc */
public void close () throws NamingException
{
myProps = null;
defaultInitCtx = null;
}
+ /**
+ * This operation is not supported for the initial naming context.
+ *
+ * @throws OperationNotSupportedException always, unless the method is
+ * overridden in the derived class.
+ */
public String getNameInNamespace () throws NamingException
{
throw new OperationNotSupportedException ();
diff --git a/javax/naming/NameParser.java b/javax/naming/NameParser.java
index 1aeaf3600..004b40627 100644
--- a/javax/naming/NameParser.java
+++ b/javax/naming/NameParser.java
@@ -1,5 +1,5 @@
-/* NameParser.java --
- Copyright (C) 2000 Free Software Foundation, Inc.
+/* NameParser.java -- JNDI name parser interface
+ Copyright (C) 2000, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,8 +38,24 @@ exception statement from your version. */
package javax.naming;
+/**
+ * Parser the string representation of the given name into the {@link Name}
+ * representation.
+ *
+ * @see Context#getNameParser(String)
+ * @see Context#getNameParser(Name)
+ */
public interface NameParser
-{
+{
+ /**
+ * Parser the string name representation into the {@link Name} representation
+ *
+ * @param name the string representation of the name
+ * @return the {@link Name} representation of the name.
+ * @throws InvalidNameException if the name violates the syntax, expected by
+ * this parser
+ * @throws NamingException if some other naming exception occurs
+ */
Name parse (String name) throws NamingException;
}
diff --git a/javax/naming/NamingEnumeration.java b/javax/naming/NamingEnumeration.java
index 3c9ee2d01..86b1dfb41 100644
--- a/javax/naming/NamingEnumeration.java
+++ b/javax/naming/NamingEnumeration.java
@@ -1,5 +1,5 @@
-/* NamingEnumeration.java --
- Copyright (C) 2000 Free Software Foundation, Inc.
+/* NamingEnumeration.java -- The JNDI enumeration
+ Copyright (C) 2000, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -40,9 +40,50 @@ package javax.naming;
import java.util.Enumeration;
+/**
+ * <p>The specific type of enumeration that supports throwing various exceptions by
+ * the hasMore method. The exceptions are only thrown if the enumeration is
+ * scanned using {@link #next()} and {@link #hasMore()}. If the inherited
+ * {@link java.util.Enumeration#nextElement()} and
+ * {@link Enumeration#hasMoreElements()} are used instead, the exceptions are
+ * not throwed, and the enumeration is just iterated over available elements.
+ * </p>
+ * <p>This enumeration becomes invalid after throwing the exception. If the
+ * exception has been thrown, not other method should be called of that
+ * enumeration.</p>
+ */
public interface NamingEnumeration extends Enumeration
{
- void close() throws NamingException;
- boolean hasMore() throws NamingException;
+ /**
+ * Returns the next element in this enumeration. The naming - specific
+ * exceptions are only throws after returning all still available elements of
+ * the enumeration.
+ *
+ * @return the next element of this enumeration
+ * @throws NamingException
+ */
Object next() throws NamingException;
+
+ /**
+ * Checks if there are more unvisited elements in the enumeration, throwing
+ * exceptions if there are some unvisited, but not available elements.
+ *
+ * @return true if there are some unvisited elements, false otherwise.
+ * @throws PartialResultException if the enumeration, returned by the
+ * {@link Context#list(Name)} or other similar method contains only
+ * partial answer.
+ * @throws SizeLimitExceededException if remaining elements are not available
+ * because of the previously specified size limit.
+ * @throws NamingException
+ */
+ boolean hasMore() throws NamingException;
+
+ /**
+ * Immediately frees all resources, owned by this enumeration. If invoked, it
+ * must be the last method called for that enumeration.
+ *
+ * @throws NamingException
+ */
+ void close() throws NamingException;
+
}
diff --git a/javax/naming/PartialResultException.java b/javax/naming/PartialResultException.java
index 61660781f..28f0467fe 100644
--- a/javax/naming/PartialResultException.java
+++ b/javax/naming/PartialResultException.java
@@ -38,7 +38,11 @@ exception statement from your version. */
package javax.naming;
-
+/**
+ * Thrown from the {@link javax.naming.NamingEnumeration}, this exception
+ * indicates that the enumeration represents only part of the existing
+ * elements that would be an answer to the specified request.
+ */
public class PartialResultException extends NamingException
{
private static final long serialVersionUID = 2572144970049426786L;
diff --git a/javax/naming/Reference.java b/javax/naming/Reference.java
index 5b9883aec..0fdecc19e 100644
--- a/javax/naming/Reference.java
+++ b/javax/naming/Reference.java
@@ -43,54 +43,118 @@ import java.util.Enumeration;
import java.util.Vector;
/**
+ * This class represents a reference to an object that is located outside of the
+ * naming/directory system.
+ *
+ * @see Referenceable
+ *
* @author Tom Tromey (tromey@redhat.com)
- * @date May 16, 2001
*/
public class Reference implements Cloneable, Serializable
{
private static final long serialVersionUID = - 1673475790065791735L;
-
+
+ /**
+ * The list of addresses, stored in this reference. The object may be
+ * have by several different addresses.
+ */
+ protected Vector addrs;
+
+ /**
+ * The name of the class factory to create an instance of the object,
+ * referenced by this reference.
+ */
+ protected String classFactory;
+
+ /**
+ * The location, from where the class factory should be loaded.
+ */
+ protected String classFactoryLocation;
+
+ /**
+ * The name of the class of the object, to that this reference refers.
+ */
+ protected String className;
+
+ /**
+ * Create a new reference that is referencting to the object of the
+ * specified class.
+ */
public Reference (String className)
{
this.className = className;
addrs = new Vector ();
}
-
+
+ /**
+ * Create a new reference that is referencing to the object of the
+ * specified class with the given address.
+ */
public Reference (String className, RefAddr addr)
{
this.className = className;
addrs = new Vector ();
addrs.add (addr);
}
-
- public Reference (String className, String factory, String factoryLocation)
+
+ /**
+ * Create a new reference that is referencing to the object of the
+ * specified class, specifying the class and location of the factory that
+ * produces these objects.
+ *
+ * @param className the object class name
+ * @param factoryClassName the object factory class name
+ * @param factoryLocation the object factory location
+ */
+ public Reference (String className, String factoryClassName,
+ String factoryLocation)
{
this.className = className;
- this.classFactory = factory;
+ this.classFactory = factoryClassName;
this.classFactoryLocation = factoryLocation;
addrs = new Vector ();
}
+ /**
+ * Create a new reference that is referencing to the object of the
+ * specified class, specifying the class and location of the factory that
+ * produces these objects and also the address of this object.
+ *
+ * @param className the object class name
+ * @param addr the address of the object
+ * @param factoryClassName the object factory class name
+ * @param factoryLocation the object factory location
+ */
public Reference (String className, RefAddr addr,
- String factory, String factoryLocation)
+ String factoryClassName, String factoryLocation)
{
this.className = className;
- this.classFactory = factory;
+ this.classFactory = factoryClassName;
this.classFactoryLocation = factoryLocation;
addrs = new Vector ();
addrs.add (addr);
}
+ /**
+ * Add the new address for this object at the given position of the
+ * address list.
+ */
public void add (int posn, RefAddr addr)
{
addrs.add (posn, addr);
}
-
+
+ /**
+ * Appends the new object address to the end of the address list.
+ */
public void add (RefAddr addr)
{
addrs.add (addr);
}
-
+
+ /**
+ * Removes all defined addresses of the object.
+ */
public void clear ()
{
addrs.clear ();
@@ -109,7 +173,10 @@ public class Reference implements Cloneable, Serializable
{
return (a == null) ? (b == null) : a.equals (b);
}
-
+
+ /**
+ * Compares two addresses for equality, by value.
+ */
public boolean equals (Object obj)
{
if (! (obj instanceof Reference))
@@ -120,12 +187,23 @@ public class Reference implements Cloneable, Serializable
&& equals (className, r.className)
&& addrs.equals (r.addrs));
}
-
+
+ /**
+ * Get the address of this object at the given position.
+ */
public RefAddr get (int posn)
{
return (RefAddr) addrs.get (posn);
}
-
+
+ /**
+ * Get the given type of address for this object.
+ *
+ * @param addrType the needed type of address
+ *
+ * @return the address of this object, having the specified type. If there
+ * is no address of such type, null is returned.
+ */
public RefAddr get (String addrType)
{
for (int i = 0; i < addrs.size (); ++i)
@@ -136,27 +214,50 @@ public class Reference implements Cloneable, Serializable
}
return null;
}
-
+
+ /**
+ * Get the enumeration over all defined addresses of the object.
+ */
public Enumeration getAll ()
{
return addrs.elements ();
}
-
+
+ /**
+ * Get the name of the class of the referenced object.
+ *
+ * @see #className
+ */
public String getClassName ()
{
return className;
}
-
+
+ /**
+ * Get the location of the factory class of the referenced object.
+ *
+ * @see #classFactoryLocation
+ */
public String getFactoryClassLocation ()
{
return classFactoryLocation;
}
+ /**
+ * Get the name of the factory class of the referenced object
+ *
+ * @see #classFactory
+ */
public String getFactoryClassName ()
{
return classFactory;
}
-
+
+ /**
+ * Get the hashcode of this reference.
+ *
+ * @return the sum of the hash codes of the addresses.
+ */
public int hashCode ()
{
// The spec says the hash code is the sum of the hash codes of the
@@ -166,17 +267,30 @@ public class Reference implements Cloneable, Serializable
h += addrs.get (i).hashCode ();
return h;
}
-
+
+ /**
+ * Remove the address at the given position.
+ *
+ * @param posn the position of the address to remove
+ *
+ * @return the removed address
+ */
public Object remove (int posn)
{
return addrs.remove (posn);
}
-
+
+ /**
+ * Return the number of the defined addresses.
+ */
public int size ()
{
return addrs.size ();
}
-
+
+ /**
+ * Return the string representation.
+ */
public String toString ()
{
String x = getClass ().toString () + "[";
@@ -189,8 +303,4 @@ public class Reference implements Cloneable, Serializable
return x + "]";
}
- protected Vector addrs;
- protected String classFactory;
- protected String classFactoryLocation;
- protected String className;
}
diff --git a/javax/naming/Referenceable.java b/javax/naming/Referenceable.java
index cf1100aab..21c5238bc 100644
--- a/javax/naming/Referenceable.java
+++ b/javax/naming/Referenceable.java
@@ -1,5 +1,5 @@
/* Referenceable.java --
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,19 @@ exception statement from your version. */
package javax.naming;
+/**
+ * The object, implementing this interface, can provided the
+ * {@link Reference} about itself.
+ */
public interface Referenceable
{
+ /**
+ * Get the reference about this object.
+ *
+ * @return the reference about this object, cannot be null.
+ *
+ * @throws NamingException if the naming exception has been raised while
+ * retrieving the reference.
+ */
Reference getReference() throws NamingException;
}
diff --git a/javax/naming/SizeLimitExceededException.java b/javax/naming/SizeLimitExceededException.java
index 3ca9a23b7..caffa70c3 100644
--- a/javax/naming/SizeLimitExceededException.java
+++ b/javax/naming/SizeLimitExceededException.java
@@ -38,7 +38,12 @@ exception statement from your version. */
package javax.naming;
-
+/**
+ * Thrown from the {@link javax.naming.NamingEnumeration}, this exception
+ * indicates that there are more elements than the previously specified
+ * size limit. Hence the enumeration represents only part of the existing
+ * elements that would be an answer to the specified request.
+ */
public class SizeLimitExceededException extends LimitExceededException
{
private static final long serialVersionUID = 7129289564879168579L;
diff --git a/javax/naming/spi/InitialContextFactory.java b/javax/naming/spi/InitialContextFactory.java
index 7bfcf095e..d9b3336dc 100644
--- a/javax/naming/spi/InitialContextFactory.java
+++ b/javax/naming/spi/InitialContextFactory.java
@@ -43,7 +43,28 @@ import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingException;
+/**
+ * <p>
+ * Defines a factory that creates the initial context for the beginning of the
+ * name resolution. JNDI allows to specify different implementations of the
+ * initial context at runtime.
+ * </p>
+ * <p>
+ * The class, implementing this interface, must be public and have a public
+ * parameterless constructor
+ * </p>
+ */
public interface InitialContextFactory
{
- Context getInitialContext (Hashtable environment) throws NamingException;
+ /**
+ * Create a new initial context
+ *
+ * @param environment the properties, used when creating the context. The
+ * implementing class will not modify the table nor keep the
+ * reference to it. After the method returns, the caller can safely
+ * reuse the table for other purposes.
+ * @return the new initial context
+ * @throws NamingException if the naming exception has occured
+ */
+ Context getInitialContext(Hashtable environment) throws NamingException;
}
diff --git a/javax/naming/spi/InitialContextFactoryBuilder.java b/javax/naming/spi/InitialContextFactoryBuilder.java
index 76564ab5e..4696cecb8 100644
--- a/javax/naming/spi/InitialContextFactoryBuilder.java
+++ b/javax/naming/spi/InitialContextFactoryBuilder.java
@@ -42,8 +42,25 @@ import java.util.Hashtable;
import javax.naming.NamingException;
+/**
+ * Represents the builder that creates instances of the factories that produce
+ * initial naming contexts. JNDI allows to specifiy different initial contexts
+ * at runtime. The user program can install its own initial context factory
+ * builder.
+ *
+ * @see NamingManager#setInitialContextFactoryBuilder
+ */
public interface InitialContextFactoryBuilder
{
+ /**
+ * Create the new inital context factory
+ *
+ * @param environment the properties, used for creation of the initial context
+ * factory. The parameter is owned by the caller: it is safe to reuse
+ * the table for other purposes after the method returns.
+ * @return the created initial context factory, never null.
+ * @throws NamingException on failure
+ */
InitialContextFactory createInitialContextFactory (Hashtable environment)
throws NamingException;
}
diff --git a/javax/naming/spi/NamingManager.java b/javax/naming/spi/NamingManager.java
index cfc9dbd5f..a36d519d7 100644
--- a/javax/naming/spi/NamingManager.java
+++ b/javax/naming/spi/NamingManager.java
@@ -1,5 +1,6 @@
-/* NamingManager.java --
- Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+/* NamingManager.java -- Creates contexts and objects
+ Copyright (C) 2000, 2001, 2002, 2003, 2004,
+ 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,6 +39,8 @@ exception statement from your version. */
package javax.naming.spi;
+import gnu.classpath.VMStackWalker;
+
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.StringTokenizer;
@@ -52,8 +55,19 @@ import javax.naming.Reference;
import javax.naming.Referenceable;
import javax.naming.StringRefAddr;
+/**
+ * Contains methods for creating contexts and objects referred to by
+ * location information. The location is specified in the scope of the
+ * certain naming or directory service. This class only contais static
+ * methods and cannot be instantiated.
+ */
public class NamingManager
{
+ /**
+ * The environment property into which getContinuationContext() stores the
+ * value of the CannotProceedException parameter. The value of this field
+ * is <i>java.naming.spi.CannotProceedException<i>.
+ */
public static final String CPE = "java.naming.spi.CannotProceedException";
private static InitialContextFactoryBuilder icfb;
@@ -65,12 +79,37 @@ public class NamingManager
NamingManager ()
{
}
-
+
+ /**
+ * Checks if the initial context factory builder has been set.
+ *
+ * @return true if the builder has been set
+ *
+ * @see #setInitialContextFactoryBuilder(InitialContextFactoryBuilder)
+ */
public static boolean hasInitialContextFactoryBuilder ()
{
return icfb != null;
}
+ /**
+ * Creates the initial context. If the initial object factory builder has
+ * been set with {@link #setObjectFactoryBuilder(ObjectFactoryBuilder)},
+ * the work is delegated to this builder. Otherwise, the method searches
+ * for the property Context.INITIAL_CONTEXT_FACTORY first in the passed
+ * table and then in the system properties. The value of this property is
+ * uses as a class name to install the context factory. The corresponding
+ * class must exist, be public and have the public parameterless constructor.
+ *
+ * @param environment the properties, used to create the context.
+ *
+ * @return the created context
+ *
+ * @throws NoInitialContextException if the initial builder is not set,
+ * the property Context.INITIAL_CONTEXT_FACTORY is missing of the
+ * class, named by this property, cannot be instantiated.
+ * @throws NamingException if throws by the context factory
+ */
public static Context getInitialContext (Hashtable environment)
throws NamingException
{
@@ -112,77 +151,191 @@ public class NamingManager
return icf.getInitialContext (environment);
}
-
- static Context getURLContext (Object refInfo,
- Name name,
- Context nameCtx,
- String scheme,
- Hashtable environment)
- throws NamingException
+
+ /**
+ * <p>
+ * Creates the URL context for the given URL scheme id.
+ * </p>
+ * <p>
+ * The class name of the factory that creates the context has the naming
+ * pattern scheme-idURLContextFactory. For instance, the factory for the "ftp"
+ * sheme should be named "ftpURLContextFactory".
+ * </p>
+ * <p>
+ * The Context.URL_PKG_PREFIXES environment property contains the
+ * colon-separated list of the possible package prefixes. The package name is
+ * constructed concatenating the package prefix with the scheme id. This
+ * property is searched in the passed <i>environment</i> parameter and later
+ * in the system properties.
+ * </p>
+ * <p>
+ * If the factory class cannot be found in the specified packages, system will
+ * try to use the default internal factory for the given scheme.
+ * </p>
+ * <p>
+ * After the factory is instantiated, its method
+ * {@link ObjectFactory#getObjectInstance(Object, Name, Context, Hashtable)}
+ * is called to create and return the object instance.
+ *
+ * @param refInfo passed to the factory
+ * @param name passed to the factory
+ * @param nameCtx passed to the factory
+ * @param scheme the url scheme that must be supported by the given context
+ * @param environment the properties for creating the factory and context (may
+ * be null)
+ * @return the created context
+ * @throws NamingException if thrown by the factory when creating the context.
+ */
+ static Context getURLContext(Object refInfo, Name name, Context nameCtx,
+ String scheme, Hashtable environment)
+ throws NamingException
{
- String prefixes = null;
+ // Specified as the default in the docs. Unclear if this is
+ // right for us.
+ String defaultPrefix = "com.sun.jndi.url";
+
+ StringBuffer allPrefixes = new StringBuffer();
+
+ String prefixes;
if (environment != null)
- prefixes = (String) environment.get (Context.URL_PKG_PREFIXES);
- if (prefixes == null)
- prefixes = System.getProperty (Context.URL_PKG_PREFIXES);
- if (prefixes == null)
{
- // Specified as the default in the docs. Unclear if this is
- // right for us.
- prefixes = "com.sun.jndi.url";
+ prefixes = (String) environment.get(Context.URL_PKG_PREFIXES);
+ if (prefixes != null)
+ allPrefixes.append(prefixes);
+ }
+
+ prefixes = System.getProperty(Context.URL_PKG_PREFIXES);
+ if (prefixes != null)
+ {
+ if (allPrefixes.length() > 0)
+ allPrefixes.append(':');
+ allPrefixes.append(prefixes);
}
+ if (allPrefixes.length() > 0)
+ allPrefixes.append(':');
+ allPrefixes.append(defaultPrefix);
+
scheme = scheme + "." + scheme + "URLContextFactory";
- StringTokenizer tokens = new StringTokenizer (prefixes, ":");
- while (tokens.hasMoreTokens ())
+ StringTokenizer tokens = new StringTokenizer(allPrefixes.toString(), ":");
+ while (tokens.hasMoreTokens())
{
- String aTry = tokens.nextToken ();
- try
- {
- Class factoryClass = Class.forName (aTry + "." + scheme,
- true,
- Thread.currentThread().getContextClassLoader());
- ObjectFactory factory =
- (ObjectFactory) factoryClass.newInstance ();
- Object obj = factory.getObjectInstance (refInfo, name,
- nameCtx, environment);
- Context ctx = (Context) obj;
- if (ctx != null)
- return ctx;
- }
- catch (ClassNotFoundException _1)
- {
- // Ignore it.
- }
- catch (ClassCastException _2)
- {
- // This means that the class we found was not an
- // ObjectFactory or that the factory returned something
- // which was not a Context.
- }
- catch (InstantiationException _3)
- {
- // If we couldn't instantiate the factory we might get
- // this.
- }
- catch (IllegalAccessException _4)
- {
- // Another possibility when instantiating.
- }
- catch (NamingException _5)
- {
- throw _5;
- }
- catch (Exception _6)
- {
- // Anything from getObjectInstance.
- }
+ String aTry = tokens.nextToken();
+ try
+ {
+ String tryClass = aTry + "." + scheme;
+ Class factoryClass = forName(tryClass);
+ if (factoryClass != null)
+ {
+ ObjectFactory factory = (ObjectFactory) factoryClass.newInstance();
+ Object obj = factory.getObjectInstance(refInfo, name, nameCtx,
+ environment);
+ Context ctx = (Context) obj;
+ if (ctx != null)
+ return ctx;
+ }
+ }
+ catch (ClassNotFoundException _1)
+ {
+ // Ignore it.
+ }
+ catch (ClassCastException _2)
+ {
+ // This means that the class we found was not an
+ // ObjectFactory or that the factory returned something
+ // which was not a Context.
+ }
+ catch (InstantiationException _3)
+ {
+ // If we couldn't instantiate the factory we might get
+ // this.
+ }
+ catch (IllegalAccessException _4)
+ {
+ // Another possibility when instantiating.
+ }
+ catch (NamingException _5)
+ {
+ throw _5;
+ }
+ catch (Exception _6)
+ {
+ // Anything from getObjectInstance.
+ }
}
return null;
}
-
+
+ /**
+ * Load the class with the given name. This method tries to use the context
+ * class loader first. If this fails, it searches for the suitable class
+ * loader in the caller stack trace. This method is a central point where all
+ * requests to find a class by name are delegated.
+ */
+ static Class forName(String className)
+ {
+ try
+ {
+ return Class.forName(className, true,
+ Thread.currentThread().getContextClassLoader());
+ }
+ catch (ClassNotFoundException nex)
+ {
+ /**
+ * Returns the first user defined class loader on the call stack, or
+ * null when no non-null class loader was found.
+ */
+ Class[] ctx = VMStackWalker.getClassContext();
+ for (int i = 0; i < ctx.length; i++)
+ {
+ // Since we live in a class loaded by the bootstrap
+ // class loader, getClassLoader is safe to call without
+ // needing to be wrapped in a privileged action.
+ ClassLoader cl = ctx[i].getClassLoader();
+ try
+ {
+ if (cl != null)
+ return Class.forName(className, true, cl);
+ }
+ catch (ClassNotFoundException nex2)
+ {
+ // Try next.
+ }
+ }
+ }
+ return null;
+ }
+
+
+ /**
+ * <p>
+ * Creates the URL context for the given URL scheme id.
+ * </p>
+ * <p>
+ * The class name of the factory that creates the context has the naming
+ * pattern scheme-idURLContextFactory. For instance, the factory for the "ftp"
+ * sheme should be named "ftpURLContextFactory". The Context.URL_PKG_PREFIXES
+ * environment property contains the colon-separated list of the possible
+ * package prefixes. The package name is constructed concatenating the package
+ * prefix with the scheme id.
+ * </p>
+ * <p>
+ * If the factory class cannot be found in the specified packages, system will
+ * try to use the default internal factory for the given scheme.
+ * </p>
+ * <p>
+ * After the factory is instantiated, its method
+ * {@link ObjectFactory#getObjectInstance(Object, Name, Context, Hashtable)}
+ * is called to create and return the object instance.
+ *
+ * @param scheme the url scheme that must be supported by the given context
+ * @param environment the properties for creating the factory and context (may
+ * be null)
+ * @return the created context
+ * @throws NamingException if thrown by the factory when creating the context.
+ */
public static Context getURLContext (String scheme,
Hashtable environment)
throws NamingException
@@ -190,6 +343,17 @@ public class NamingManager
return getURLContext (null, null, null, scheme, environment);
}
+ /**
+ * Sets the initial object factory builder.
+ *
+ * @param builder the builder to set
+ *
+ * @throws SecurityException if the builder cannot be installed due
+ * security restrictions.
+ * @throws NamingException if the builder cannot be installed due other
+ * reasons
+ * @throws IllegalStateException if setting the builder repeatedly
+ */
public static void setObjectFactoryBuilder (ObjectFactoryBuilder builder)
throws NamingException
{
@@ -198,7 +362,7 @@ public class NamingManager
sm.checkSetFactory ();
// Once the builder is installed it cannot be replaced.
if (ofb != null)
- throw new IllegalStateException ("builder already installed");
+ throw new IllegalStateException ("object factory builder already installed");
if (builder != null)
ofb = builder;
}
@@ -217,7 +381,58 @@ public class NamingManager
path += ":" + path2;
return new StringTokenizer (path != null ? path : "", ":");
}
-
+
+ /**
+ * <p>Creates an object for the specified name context, environment and
+ * referencing context object.</p>
+ * <p>
+ * If the builder factory is set by
+ * {@link #setObjectFactoryBuilder(ObjectFactoryBuilder)}, the call is
+ * delegated to that factory. Otherwise, the object is created using the
+ * following rules:
+ * <ul>
+ * <li>If the referencing object (refInfo) contains the factory class name,
+ * the object is created by this factory. If the creation fails,
+ * the parameter refInfo is returned as the method return value.</li>
+ * <li>If the referencing object has no factory class name, and the addresses
+ * are StringRefAddrs having the address type "URL", the object is
+ * created by the URL context factory. The used factory corresponds the
+ * the naming schema of the each URL. If the attempt to create
+ * the object this way is not successful, the subsequent rule is
+ * tried.</li>
+ * <li> If the refInfo is not an instance of Reference or Referencable
+ * (for example, null), the object is created by the factories,
+ * specified in the Context.OBJECT_FACTORIES property of the
+ * environment and the provider resource file, associated with the
+ * nameCtx. The value of this property is the colon separated list
+ * of the possible factories. If none of the factories can be
+ * loaded, the refInfo is returned.
+ * </ul>
+ * </p>
+ * <p>The object factory must be public and have the public parameterless
+ * constructor.</p>
+ *
+ * @param refInfo the referencing object, for which the new object must be
+ * created (can be null). If not null, it is usually an instance of
+ * the {@link Reference} or {@link Referenceable}.
+ * @param name the name of the object. The name is relative to
+ * the nameCtx naming context. The value of this parameter can be
+ * null if the name is not specified.
+ * @param nameCtx the naming context, in which scope the name of the new
+ * object is specified. If this parameter is null, the name is
+ * specified in the scope of the initial context.
+ * @param environment contains additional information for creating the object.
+ * This paramter can be null if there is no need to provide any
+ * additional information.
+ *
+ * @return the created object. If the creation fails, in some cases
+ * the parameter refInfo may be returned.
+ *
+ * @throws NamingException if the attempt to name the new object has failed
+ * @throws Exception if the object factory throws it. The object factory
+ * only throws an exception if it does not want other factories
+ * to be used to create the object.
+ */
public static Object getObjectInstance (Object refInfo,
Name name,
Context nameCtx,
@@ -312,7 +527,21 @@ public class NamingManager
return obj == null ? refInfo : obj;
}
- public static void setInitialContextFactoryBuilder (InitialContextFactoryBuilder builder)
+ /**
+ * Sets the initial context factory builder.
+ *
+ * @param builder the builder to set
+ *
+ * @throws SecurityException if the builder cannot be installed due
+ * security restrictions.
+ * @throws NamingException if the builder cannot be installed due other
+ * reasons
+ * @throws IllegalStateException if setting the builder repeatedly
+ *
+ * @see #hasInitialContextFactoryBuilder()
+ */
+ public static void setInitialContextFactoryBuilder
+ (InitialContextFactoryBuilder builder)
throws NamingException
{
SecurityManager sm = System.getSecurityManager ();
@@ -320,11 +549,23 @@ public class NamingManager
sm.checkSetFactory ();
// Once the builder is installed it cannot be replaced.
if (icfb != null)
- throw new IllegalStateException ("builder already installed");
+ throw new IllegalStateException ("ctx factory builder already installed");
if (builder != null)
icfb = builder;
}
-
+
+ /**
+ * Creates a context in which the context operation must be continued.
+ * This method is used by operations on names that span multiple namespaces.
+ *
+ * @param cpe the exception that triggered this continuation. This method
+ * obtains the environment ({@link CannotProceedException#getEnvironment()}
+ * and sets the environment property {@link #CPE} = cpe.
+ *
+ * @return a non null context for continuing the operation
+ *
+ * @throws NamingException if the naming problems have occured
+ */
public static Context getContinuationContext (CannotProceedException cpe)
throws NamingException
{
@@ -332,7 +573,7 @@ public class NamingManager
if (env != null)
env.put (CPE, cpe);
- // It is really unclear to me if this is right.
+ // TODO: Check if this implementation matches the API specification
try
{
Object obj = getObjectInstance (cpe.getResolvedObj(),
@@ -351,7 +592,22 @@ public class NamingManager
throw cpe;
}
-
+
+ /**
+ * Get the object state for binding.
+ *
+ * @param obj the object, for that the binding state must be retrieved. Cannot
+ * be null.
+ * @param name the name of this object, related to the nameCtx. Can be null if
+ * not specified.
+ * @param nameCtx the naming context, to that the object name is related. Can
+ * be null if the name is related to the initial default context.
+ * @param environment the properties for creating the object state. Can be
+ * null if no properties are provided.
+ * @return the object state for binding, may be null if no changes are
+ * returned by the factory
+ * @throws NamingException
+ */
public static Object getStateToBind (Object obj, Name name,
Context nameCtx, Hashtable environment)
throws NamingException
diff --git a/javax/naming/spi/ObjectFactory.java b/javax/naming/spi/ObjectFactory.java
index 81648d9a8..27771b6cb 100644
--- a/javax/naming/spi/ObjectFactory.java
+++ b/javax/naming/spi/ObjectFactory.java
@@ -1,5 +1,5 @@
/* ObjectFactory.java --
- Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2004, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -43,9 +43,33 @@ import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.Name;
+/**
+ * Represents a factory for creating the object. ObjectFactory performs the
+ * operation, that is the opposite to the operation, performed by the
+ * {@link StateFactory}. Classes, implementing this interface, must be public
+ * and have public parameterless constructor.
+ */
public interface ObjectFactory
{
- Object getObjectInstance (Object obj, Name name, Context nameCtx,
- Hashtable environment)
- throws Exception;
+ /**
+ * Creates the object, using the specified name and location information. The
+ * call of this method must be thread safe.
+ *
+ * @param refObj may provide the reference and location information. Can be null.
+ * @param name the name of the new object in the scope of the specified naming
+ * context. Can be null if the name is not specified.
+ * @param nameCtx the context, in which the object name is specified. Can be
+ * null if the name is specified in the scope of the default initial
+ * context.
+ * @param environment the properties, providing additional information on how
+ * to create an object. Can be null if not additional information is
+ * provided.
+ * @return the newly created object or null if the object cannot be created
+ * @throws Exception if this factory suggest not to try creating of this
+ * object by other alternative factories
+ *
+ * @see NamingManager#getObjectInstance(Object, Name, Context, Hashtable)
+ */
+ Object getObjectInstance(Object refObj, Name name, Context nameCtx,
+ Hashtable environment) throws Exception;
}
diff --git a/javax/naming/spi/ObjectFactoryBuilder.java b/javax/naming/spi/ObjectFactoryBuilder.java
index a76139315..cb20c666e 100644
--- a/javax/naming/spi/ObjectFactoryBuilder.java
+++ b/javax/naming/spi/ObjectFactoryBuilder.java
@@ -1,5 +1,5 @@
-/* ObjectFactoryBuilder.java --
- Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+/* ObjectFactoryBuilder.java -- the builder that creates the object factories.
+ Copyright (C) 2001, 2004, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -41,14 +41,30 @@ package javax.naming.spi;
import java.util.Hashtable;
import javax.naming.NamingException;
+import javax.naming.Reference;
+import javax.naming.Referenceable;
/**
+ * Represents the builder that creates the object factories.
+ *
+ * @see NamingManager#setObjectFactoryBuilder(ObjectFactoryBuilder)
+ *
* @author Warren Levy (warrenl@redhat.com)
- * @date June 1, 2001
*/
public interface ObjectFactoryBuilder
-{
- ObjectFactory createObjectFactory(Object obj,
+{
+ /**
+ * Create a new object using the supplied environment.
+ *
+ * @param refInfo the referencing object, for which the new object must be
+ * created (can be null). If not null, it is usually an instance of
+ * the {@link Reference} or {@link Referenceable}.
+ * @param environment contains the additional information about the factory
+ * being created. Can be null.
+ * @return the created object factory. The null is never returned.
+ * @throws NamingException
+ */
+ ObjectFactory createObjectFactory(Object refInfo,
Hashtable environment)
throws NamingException;
}
diff --git a/javax/naming/spi/ResolveResult.java b/javax/naming/spi/ResolveResult.java
index 07e2df3c0..d5051a5d4 100644
--- a/javax/naming/spi/ResolveResult.java
+++ b/javax/naming/spi/ResolveResult.java
@@ -45,8 +45,11 @@ import javax.naming.InvalidNameException;
import javax.naming.Name;
/**
+ * Stores the partial resolution of the name. This class contains the
+ * object to which part of the name has been resolved and the remaining,
+ * unresolved part of this name.
+ *
* @author Warren Levy (warrenl@redhat.com)
- * @date June 5, 2001
*/
public class ResolveResult implements Serializable
@@ -54,51 +57,92 @@ public class ResolveResult implements Serializable
private static final long serialVersionUID = - 4552108072002407559L;
// Serialized fields.
+ /**
+ * The object, to that part of the name has been resolved.
+ */
protected Object resolvedObj;
+
+ /**
+ * The remaining, unresolved part of the name.
+ */
protected Name remainingName;
-
+
+ /**
+ * Create the unitialised instance with both parts being null.
+ */
protected ResolveResult()
{
- resolvedObj = null;
- remainingName = null;
}
-
- public ResolveResult(Object robj, String rcomp)
+
+ /**
+ * Create the initialised instance
+ *
+ * @param resolved the object, to that the name is partially resolved
+ * @param remaining the remaining unresolved part of the name.
+ */
+ public ResolveResult(Object resolved, String remaining)
{
- if (robj == null || rcomp == null)
+ if (resolved == null || remaining == null)
throw new IllegalArgumentException ();
- resolvedObj = robj;
+ resolvedObj = resolved;
remainingName = new CompositeName ();
try
{
- remainingName.add (rcomp);
+ remainingName.add (remaining);
}
catch (InvalidNameException _)
{
}
}
- public ResolveResult(Object robj, Name rname)
+ /**
+ * Create the initialised instance
+ *
+ * @param resolved the object, to that the name is partially resolved
+ * @param remaining the remaining unresolved part of the name.
+ */
+ public ResolveResult(Object resolved, Name remaining)
{
- resolvedObj = robj;
- remainingName = rname;
+ resolvedObj = resolved;
+ remainingName = remaining;
}
+ /**
+ * Get the remaining unresolved part of the name
+ *
+ * @return the remaining unresolved part of the name.
+ */
public Name getRemainingName()
{
return remainingName;
}
+ /**
+ * Get the object to that the name was partially resolved
+ *
+ * @return the object, to that the name is partially resolved
+ */
public Object getResolvedObj()
{
return resolvedObj;
}
-
+
+ /**
+ * Set the remaining unresolved name.
+ *
+ * @param name the name being set. The passed parameter is cloned, so the
+ * caller can reuse or modify it after the method returns.
+ */
public void setRemainingName(Name name)
{
remainingName = (Name) name.clone();
}
-
+
+ /**
+ * Append the name to the end of the resolved name.
+ *
+ * @param name the name to append
+ */
public void appendRemainingName(Name name)
{
try
@@ -110,6 +154,11 @@ public class ResolveResult implements Serializable
}
}
+ /**
+ * Append the name to the end of the resolved name.
+ *
+ * @param name the name to append
+ */
public void appendRemainingComponent(String name)
{
try
@@ -121,6 +170,11 @@ public class ResolveResult implements Serializable
}
}
+ /**
+ * Set the object to that the part of the name has been resolved.
+ *
+ * @param obj the object, to that the name has been partially resolved.
+ */
public void setResolvedObj(Object obj)
{
resolvedObj = obj;
diff --git a/javax/naming/spi/Resolver.java b/javax/naming/spi/Resolver.java
index d80fb6169..eb3eeb560 100644
--- a/javax/naming/spi/Resolver.java
+++ b/javax/naming/spi/Resolver.java
@@ -1,5 +1,5 @@
/* Resolver.java --
- Copyright (C) 2001, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,18 +38,47 @@ exception statement from your version. */
package javax.naming.spi;
+import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingException;
+import javax.naming.NotContextException;
/**
+ * <p>Represents the object, capable for the at least partial name resolution.
+ * The object is not necessay capable for the complete name resolution and
+ * need not implement the {@link Context}.</p>
+ * <p>
+ * Both passed parameters and returned results are owned by the caller.</p>
+ *
* @author Warren Levy (warrenl@redhat.com)
- * @date June 1, 2001
*/
-
public interface Resolver
{
+ /**
+ * Partially resolve the name, stopping at the first instance of the context
+ * that is an instance of the contextType
+ *
+ * @param name the name to resolve
+ * @param contextType the class of the context, on that the resolution should
+ * be terminated
+ * @return the complete or partial name resolution
+ * @throws NotContextException if the context of the contextType is not found
+ * @throws NamingException on other failure
+ */
ResolveResult resolveToClass(Name name, Class contextType)
throws NamingException;
+
+ /**
+ * Partially resolve the name, stopping at the first instance of the context
+ * that is an instance of the contextType
+ *
+ * @param name the name to resolve
+ * @param contextType the class of the context, on that the resolution should
+ * be terminated
+ * @return the complete or partial name resolution
+ * @throws NotContextException if the context of the contextType is not found
+ * @throws NamingException on other failure
+ */
ResolveResult resolveToClass(String name, Class contextType)
throws NamingException;
}
diff --git a/javax/naming/spi/StateFactory.java b/javax/naming/spi/StateFactory.java
index 1fbdeb1fa..5694f8a1a 100644
--- a/javax/naming/spi/StateFactory.java
+++ b/javax/naming/spi/StateFactory.java
@@ -1,5 +1,5 @@
/* StateFactory.java --
- Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2004, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -45,11 +45,35 @@ import javax.naming.Name;
import javax.naming.NamingException;
/**
+ * Represents a factory, producing the object states for binding. The operation,
+ * performed by this factory, is the reverse operation with related to the
+ * operation, performed by the {@link ObjectFactory}. Classes, implementing
+ * this interface, must be public and have public parameterless constructor.
+ *
+ * @see DirStateFactory
+ * @see ObjectFactory
* @author Warren Levy (warrenl@redhat.com)
- * @date June 1, 2001
*/
public interface StateFactory
{
+ /**
+ * Get the object state for binding.
+ *
+ * @param obj the object, for that the binding state must be retrieved. Cannot
+ * be null.
+ * @param name the name of this object, related to the nameCtx. Can be null if
+ * not specified.
+ * @param nameCtx the naming context, to that the object name is related. Can
+ * be null if the name is related to the initial default context.
+ * @param environment the properties for creating the object state. Can be
+ * null if no properties are provided.
+ * @return the object state for binding, may be null if no changes are
+ * returned by the factory
+ * @throws NamingException
+ *
+ * @see NamingManager#getStateToBind
+ * @see DirectoryManager#getStateToBind
+ */
Object getStateToBind(Object obj, Name name, Context nameCtx,
Hashtable environment) throws NamingException;
}
diff --git a/javax/swing/CellRendererPane.java b/javax/swing/CellRendererPane.java
index b3d6f6a73..764a4c500 100644
--- a/javax/swing/CellRendererPane.java
+++ b/javax/swing/CellRendererPane.java
@@ -93,7 +93,7 @@ public class CellRendererPane extends Container implements Accessible
*/
public CellRendererPane()
{
- // Nothing to do here.
+ setVisible(false);
}
/**
diff --git a/javax/swing/DefaultButtonModel.java b/javax/swing/DefaultButtonModel.java
index 7ecf3b85f..2be18cc8a 100644
--- a/javax/swing/DefaultButtonModel.java
+++ b/javax/swing/DefaultButtonModel.java
@@ -1,5 +1,5 @@
/* DefaultButtonModel.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -63,7 +63,7 @@ import javax.swing.event.EventListenerList;
* change to the "selected" property will trigger the firing of an ItemEvent
* in addition to ChangeEvent. This is true whether the model is enabled or
* not. One other state change is special: the transition from "enabled,
- * armed and pressd" to "enabled, armed and not-pressed". This is considered
+ * armed and pressed" to "enabled, armed and not-pressed". This is considered
* the "trailing edge" of a successful mouse click, and therefore fires an
* ActionEvent in addition to a ChangeEvent. In all other respects this class
* is just a container of boolean flags.
@@ -371,7 +371,7 @@ public class DefaultButtonModel implements ButtonModel, Serializable
if (e)
stateMask = stateMask | ENABLED;
else
- stateMask = stateMask & (~ENABLED);
+ stateMask = stateMask & (~ENABLED) & (~ARMED) & (~PRESSED);
// notify interested ChangeListeners
fireStateChanged();
@@ -555,21 +555,21 @@ public class DefaultButtonModel implements ButtonModel, Serializable
* one model in a given group can have their "selected" property be
* <code>true</code> at a time.
*
- * @param g The new "group" property
+ * @param g The new "group" property (<code>null</code> permitted).
+ *
+ * @see #getGroup()
*/
public void setGroup(ButtonGroup g)
{
- if (group != g)
- {
- group = g;
- fireStateChanged();
- }
+ group = g;
}
/**
* Returns the current value of the model's "group" property.
*
* @return The value of the "group" property
+ *
+ * @see #setGroup(ButtonGroup)
*/
public ButtonGroup getGroup()
{
diff --git a/javax/swing/DefaultCellEditor.java b/javax/swing/DefaultCellEditor.java
index 9c951d395..16ed1ec68 100644
--- a/javax/swing/DefaultCellEditor.java
+++ b/javax/swing/DefaultCellEditor.java
@@ -313,7 +313,24 @@ public class DefaultCellEditor
{
JComboBox c = (JComboBox) editorComponent;
return value = c.getSelectedItem();
- }
+ }
+
+ /**
+ * Returns true to indicate that the editing cell can be selected. If the
+ * check box is not editable, expands it. If it is editable, brings
+ * focus to the editor field.
+ *
+ * @param event unused in default method
+ *
+ * @return true always
+ */
+ public boolean shouldSelectCell(EventObject event)
+ {
+ JComboBox c = (JComboBox) editorComponent;
+ if (!c.isEditable)
+ c.showPopup();
+ return true;
+ }
}
/**
diff --git a/javax/swing/DefaultDesktopManager.java b/javax/swing/DefaultDesktopManager.java
index 0304461ad..11f03a715 100644
--- a/javax/swing/DefaultDesktopManager.java
+++ b/javax/swing/DefaultDesktopManager.java
@@ -400,8 +400,8 @@ public class DefaultDesktopManager implements DesktopManager, Serializable
dragCache.width, dragCache.height);
pane = null;
dragCache = null;
+ component.repaint();
}
- component.repaint();
}
/**
@@ -463,8 +463,8 @@ public class DefaultDesktopManager implements DesktopManager, Serializable
dragCache.width, dragCache.height);
pane = null;
dragCache = null;
+ component.repaint();
}
- component.repaint();
}
/**
@@ -481,13 +481,6 @@ public class DefaultDesktopManager implements DesktopManager, Serializable
int newWidth, int newHeight)
{
component.setBounds(newX, newY, newWidth, newHeight);
- component.revalidate();
-
- // If not null, I'd rather repaint the parent
- if (component.getParent() != null)
- component.getParent().repaint();
- else
- component.repaint();
}
/**
diff --git a/javax/swing/JCheckBoxMenuItem.java b/javax/swing/JCheckBoxMenuItem.java
index 815244259..3222d189f 100644
--- a/javax/swing/JCheckBoxMenuItem.java
+++ b/javax/swing/JCheckBoxMenuItem.java
@@ -1,5 +1,5 @@
/* JCheckBoxMenuItem.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -204,7 +204,7 @@ public class JCheckBoxMenuItem extends JMenuItem implements SwingConstants,
/**
* This method overrides JComponent.requestFocus with an empty
* implementation, since JCheckBoxMenuItems should not
- * receve focus in general.
+ * receive focus in general.
*/
public void requestFocus()
{
@@ -212,16 +212,28 @@ public class JCheckBoxMenuItem extends JMenuItem implements SwingConstants,
}
/**
- * A string that describes this JCheckBoxMenuItem. Normally only used
- * for debugging.
+ * Returns a string describing the attributes for the
+ * <code>JCheckBoxMenuItem</code> component, for use in debugging. The
+ * return value is guaranteed to be non-<code>null</code>, but the format
+ * of the string may vary between implementations.
*
- * @return A string describing this JCheckBoxMenuItem
+ * @return A string describing the attributes of the
+ * <code>JCheckBoxMenuItem</code>.
*/
protected String paramString()
{
- return "JCheckBoxMenuItem";
+ // calling super seems to be sufficient to match the reference
+ // implementation here...
+ return super.paramString();
}
+ /**
+ * Returns the object that provides accessibility features for this
+ * <code>JCheckBoxMenuItem</code> component.
+ *
+ * @return The accessible context (an instance of
+ * {@link AccessibleJCheckBoxMenuItem}).
+ */
public AccessibleContext getAccessibleContext()
{
if (accessibleContext == null)
@@ -231,20 +243,29 @@ public class JCheckBoxMenuItem extends JMenuItem implements SwingConstants,
}
/**
- * Accessibility support for <code>JCheckBoxMenuItem</code>.
+ * Provides the accessibility features for the <code>JCheckBoxMenuItem</code>
+ * component.
+ *
+ * @see JCheckBoxMenuItem#getAccessibleContext()
*/
protected class AccessibleJCheckBoxMenuItem extends AccessibleJMenuItem
{
private static final long serialVersionUID = 1079958073579370777L;
/**
- * Creates a new AccessibleJCheckBoxMenuItem object.
+ * Creates a new <code>AccessibleJCheckBoxMenuItem</code> instance.
*/
protected AccessibleJCheckBoxMenuItem()
{
// Nothing to do here.
}
+ /**
+ * Returns the accessible role for the <code>JCheckBoxMenuItem</code>
+ * component.
+ *
+ * @return {@link AccessibleRole#CHECK_BOX}.
+ */
public AccessibleRole getAccessibleRole()
{
return AccessibleRole.CHECK_BOX;
diff --git a/javax/swing/JComboBox.java b/javax/swing/JComboBox.java
index 992162163..efb04592b 100644
--- a/javax/swing/JComboBox.java
+++ b/javax/swing/JComboBox.java
@@ -675,7 +675,7 @@ public class JComboBox extends JComponent implements ItemSelectable,
}
else
throw new RuntimeException("Unable to remove the items because the data "
- +"model it is not an instance of "
+ + "model it is not an instance of "
+ "MutableComboBoxModel.");
}
@@ -848,7 +848,7 @@ public class JComboBox extends JComponent implements ItemSelectable,
{
PopupMenuListener[] listeners = getPopupMenuListeners();
PopupMenuEvent e = new PopupMenuEvent(this);
- for(int i = 0; i < listeners.length; i++)
+ for (int i = 0; i < listeners.length; i++)
listeners[i].popupMenuCanceled(e);
}
@@ -862,7 +862,7 @@ public class JComboBox extends JComponent implements ItemSelectable,
{
PopupMenuListener[] listeners = getPopupMenuListeners();
PopupMenuEvent e = new PopupMenuEvent(this);
- for(int i = 0; i < listeners.length; i++)
+ for (int i = 0; i < listeners.length; i++)
listeners[i].popupMenuWillBecomeInvisible(e);
}
@@ -876,7 +876,7 @@ public class JComboBox extends JComponent implements ItemSelectable,
{
PopupMenuListener[] listeners = getPopupMenuListeners();
PopupMenuEvent e = new PopupMenuEvent(this);
- for(int i = 0; i < listeners.length; i++)
+ for (int i = 0; i < listeners.length; i++)
listeners[i].popupMenuWillBecomeVisible(e);
}
diff --git a/javax/swing/JComponent.java b/javax/swing/JComponent.java
index d916d0583..38c6aec28 100644
--- a/javax/swing/JComponent.java
+++ b/javax/swing/JComponent.java
@@ -760,13 +760,6 @@ public abstract class JComponent extends Container implements Serializable
public static final int WHEN_IN_FOCUSED_WINDOW = 2;
/**
- * Indicates if this component is completely dirty or not. This is used
- * by the RepaintManager's
- * {@link RepaintManager#isCompletelyDirty(JComponent)} method.
- */
- boolean isCompletelyDirty = false;
-
- /**
* Indicates if the opaque property has been set by a client program or by
* the UI.
*
@@ -1763,11 +1756,6 @@ public abstract class JComponent extends Container implements Serializable
paintComponent(g2);
paintBorder(g2);
paintChildren(g2);
- Rectangle clip = g2.getClipBounds();
- if (clip == null
- || (clip.x == 0 && clip.y == 0 && clip.width == getWidth()
- && clip.height == getHeight()))
- RepaintManager.currentManager(this).markCompletelyClean(this);
}
}
}
@@ -3554,6 +3542,7 @@ public abstract class JComponent extends Container implements Serializable
Rectangle currentClip = clip;
Component found = this;
Container parent = this;
+
while (parent != null && !(parent instanceof Window))
{
Container newParent = parent.getParent();
@@ -3569,15 +3558,42 @@ public abstract class JComponent extends Container implements Serializable
parent = newParent;
continue;
}
- // If the parent is not optimizedDrawingEnabled, we must paint the
- // parent.
+
+ // If the parent is not optimizedDrawingEnabled, we must check if the
+ // parent or some neighbor overlaps the current clip.
+
+ // This is the current clip converted to the parent's coordinate
+ // system. TODO: We can do this more efficiently by succesively
+ // cumulating the parent-child translations.
Rectangle target = SwingUtilities.convertRectangle(found,
currentClip,
newParent);
- found = newParent;
- currentClip = target;
+
+ // We have an overlap if either:
+ // - The new parent itself doesn't completely cover the clip
+ // (this can be the case with viewports).
+ // - If some higher-level (than the current) children of the new parent
+ // intersect the target rectangle.
+ Rectangle parentRect = SwingUtilities.getLocalBounds(newParent);
+ boolean haveOverlap =
+ ! SwingUtilities.isRectangleContainingRectangle(parentRect, target);
+ if (! haveOverlap)
+ {
+ Component[] children = newParent.getComponents();
+ for (int i = 0; children[i] != parent && !haveOverlap; i++)
+ {
+ Rectangle childRect = children[i].getBounds();
+ haveOverlap = target.intersects(childRect);
+ }
+ }
+ if (haveOverlap)
+ {
+ found = newParent;
+ currentClip = target;
+ }
parent = newParent;
}
+ //System.err.println("overlapfree parent: " + found);
return found;
}
diff --git a/javax/swing/JEditorPane.java b/javax/swing/JEditorPane.java
index 73b775738..4ae3c5a1c 100644
--- a/javax/swing/JEditorPane.java
+++ b/javax/swing/JEditorPane.java
@@ -1,5 +1,5 @@
/* JEditorPane.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -538,8 +538,8 @@ public class JEditorPane extends JTextComponent
public JEditorPane(URL url) throws IOException
{
- init ();
- setEditorKit (createEditorKitForContentType("text/html"));;
+ init();
+ setEditorKit(createEditorKitForContentType("text/html"));;
setPage(url);
}
@@ -581,7 +581,7 @@ public class JEditorPane extends JTextComponent
// TODO: Have to handle the case where a ClassLoader was specified
// when the EditorKit was registered
EditorKit e = null;
- String className = (String)registerMap.get(type);
+ String className = (String) registerMap.get(type);
if (className != null)
{
try
diff --git a/javax/swing/JFileChooser.java b/javax/swing/JFileChooser.java
index 7da3a132d..64f9bd0f4 100644
--- a/javax/swing/JFileChooser.java
+++ b/javax/swing/JFileChooser.java
@@ -1,5 +1,5 @@
/* JFileChooser.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,10 +37,9 @@ exception statement from your version. */
package javax.swing;
-import gnu.classpath.NotImplementedException;
-
import java.awt.Component;
import java.awt.Frame;
+import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -389,6 +388,13 @@ public class JFileChooser extends JComponent implements Accessible
* @see #setSelectedFile(File)
*/
private File selectedFile;
+
+ /**
+ * The drag enabled property.
+ * @see #setDragEnabled(boolean)
+ * @see #getDragEnabled()
+ */
+ private boolean dragEnabled;
/**
* Creates a new <code>JFileChooser</code> object.
@@ -487,26 +493,31 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
- *
- * @param b DOCUMENT ME!
+ * Sets the dragEnabled property, this disables/enables automatic drag
+ * handling (drag and drop) on this component. The default value of the
+ * dragEnabled property is false.
+ *
+ * Some look and feels might not support automatic drag and drop; they
+ * will ignore this property.
+ *
+ * @param b - the new dragEnabled value
*/
public void setDragEnabled(boolean b)
- throws NotImplementedException
{
- // FIXME: Implement
+ if (b && GraphicsEnvironment.isHeadless())
+ throw new HeadlessException();
+
+ dragEnabled = b;
}
/**
- * DOCUMENT ME!
+ * Returns true if dragging is enabled.
*
- * @return DOCUMENT ME!
+ * @return true if dragging is enabled.
*/
public boolean getDragEnabled()
- throws NotImplementedException
{
- // FIXME: Implement
- return false;
+ return dragEnabled;
}
/**
@@ -1514,19 +1525,60 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * DOCUMENT ME!
+ * Returns a string describing the attributes for the
+ * <code>JFileChooser</code> component, for use in debugging. The return
+ * value is guaranteed to be non-<code>null</code>, but the format of the
+ * string may vary between implementations.
*
- * @return DOCUMENT ME!
+ * @return A string describing the attributes of the
+ * <code>JFileChooser</code>.
*/
protected String paramString()
{
- return "JFileChooser";
+ StringBuffer sb = new StringBuffer(super.paramString());
+ sb.append(",approveButtonText=");
+ if (approveButtonText != null)
+ sb.append(approveButtonText);
+ sb.append(",currentDirectory=");
+ if (currentDir != null)
+ sb.append(currentDir);
+ sb.append(",dialogTitle=");
+ if (dialogTitle != null)
+ sb.append(dialogTitle);
+ sb.append(",dialogType=");
+ if (dialogType == OPEN_DIALOG)
+ sb.append("OPEN_DIALOG");
+ if (dialogType == SAVE_DIALOG)
+ sb.append("SAVE_DIALOG");
+ if (dialogType == CUSTOM_DIALOG)
+ sb.append("CUSTOM_DIALOG");
+ sb.append(",fileSelectionMode=");
+ if (fileSelectionMode == FILES_ONLY)
+ sb.append("FILES_ONLY");
+ if (fileSelectionMode == DIRECTORIES_ONLY)
+ sb.append("DIRECTORIES_ONLY");
+ if (fileSelectionMode == FILES_AND_DIRECTORIES)
+ sb.append("FILES_AND_DIRECTORIES");
+ sb.append(",returnValue=");
+ if (retval == APPROVE_OPTION)
+ sb.append("APPROVE_OPTION");
+ if (retval == CANCEL_OPTION)
+ sb.append("CANCEL_OPTION");
+ if (retval == ERROR_OPTION)
+ sb.append("ERROR_OPTION");
+ sb.append(",selectedFile=");
+ if (selectedFile != null)
+ sb.append(selectedFile);
+ sb.append(",useFileHiding=").append(fileHiding);
+ return sb.toString();
}
/**
- * Returns the accessible context.
+ * Returns the object that provides accessibility features for this
+ * <code>JFileChooser</code> component.
*
- * @return The accessible context.
+ * @return The accessible context (an instance of
+ * {@link AccessibleJFileChooser}).
*/
public AccessibleContext getAccessibleContext()
{
@@ -1536,16 +1588,26 @@ public class JFileChooser extends JComponent implements Accessible
}
/**
- * Accessibility support for JFileChooser
+ * Provides the accessibility features for the <code>JFileChooser</code>
+ * component.
*/
protected class AccessibleJFileChooser
extends JComponent.AccessibleJComponent
{
+ /**
+ * Creates a new instance of <code>AccessibleJFileChooser</code>.
+ */
protected AccessibleJFileChooser()
{
// Nothing to do here.
}
+ /**
+ * Returns the accessible role for the <code>JFileChooser</code>
+ * component.
+ *
+ * @return {@link AccessibleRole#FILE_CHOOSER}.
+ */
public AccessibleRole getAccessibleRole()
{
return AccessibleRole.FILE_CHOOSER;
diff --git a/javax/swing/JFormattedTextField.java b/javax/swing/JFormattedTextField.java
index 761955d6d..054752550 100644
--- a/javax/swing/JFormattedTextField.java
+++ b/javax/swing/JFormattedTextField.java
@@ -101,11 +101,11 @@ public class JFormattedTextField extends JTextField
* @throws CloneNotSupportedException if the Object's class doesn't support
* the {@link Cloneable} interface
*/
- protected Object clone ()
+ protected Object clone()
throws CloneNotSupportedException
{
// Clone this formatter.
- AbstractFormatter newFormatter = (AbstractFormatter)super.clone();
+ AbstractFormatter newFormatter = (AbstractFormatter) super.clone();
// And remove the association to the JFormattedTextField.
newFormatter.textField = null;
@@ -119,7 +119,7 @@ public class JFormattedTextField extends JTextField
* @return <code>null</code>. Should be subclassed by formatters that want
* to install custom Actions on the JFormattedTextField.
*/
- protected Action[] getActions ()
+ protected Action[] getActions()
{
return null;
}
@@ -132,7 +132,7 @@ public class JFormattedTextField extends JTextField
* @return <code>null</code>. Should be subclassed by formatters
* that want to restrict Document mutations.
*/
- protected DocumentFilter getDocumentFilter ()
+ protected DocumentFilter getDocumentFilter()
{
// Subclasses should override this if they want to install a
// DocumentFilter.
@@ -146,7 +146,7 @@ public class JFormattedTextField extends JTextField
* @return the JFormattedTextField on which this formatter is currently
* installed
*/
- protected JFormattedTextField getFormattedTextField ()
+ protected JFormattedTextField getFormattedTextField()
{
return textField;
}
@@ -159,7 +159,7 @@ public class JFormattedTextField extends JTextField
* @return <code>null</code>. Subclassed by formatters that want to restrict
* cursor location within the JFormattedTextField.
*/
- protected NavigationFilter getNavigationFilter ()
+ protected NavigationFilter getNavigationFilter()
{
// This should be subclassed if the formatter wants to install
// a NavigationFilter on the JFormattedTextField.
@@ -199,7 +199,7 @@ public class JFormattedTextField extends JTextField
// Set the DocumentFilter for the field's Document.
if (doc instanceof AbstractDocument)
- ((AbstractDocument)doc).setDocumentFilter(getDocumentFilter());
+ ((AbstractDocument) doc).setDocumentFilter(getDocumentFilter());
// Set the NavigationFilter.
textField.setNavigationFilter(getNavigationFilter());
@@ -221,12 +221,12 @@ public class JFormattedTextField extends JTextField
* This resets the DocumentFilter, NavigationFilter, and any additional
* Actions (returned by <code>getActions()</code>).
*/
- public void uninstall ()
+ public void uninstall()
{
// Set the DocumentFilter for the field's Document.
Document doc = textField.getDocument();
if (doc instanceof AbstractDocument)
- ((AbstractDocument)doc).setDocumentFilter(null);
+ ((AbstractDocument) doc).setDocumentFilter(null);
textField.setNavigationFilter(null);
// FIXME: Have to remove the Actions from getActions()
this.textField = null;
@@ -236,7 +236,7 @@ public class JFormattedTextField extends JTextField
* Invoke this method when invalid values are entered. This forwards the
* call to the JFormattedTextField.
*/
- protected void invalidEdit ()
+ protected void invalidEdit()
{
textField.invalidEdit();
}
@@ -247,7 +247,7 @@ public class JFormattedTextField extends JTextField
*
* @param valid the new state for the <code>editValid</code> property
*/
- protected void setEditValid (boolean valid)
+ protected void setEditValid(boolean valid)
{
textField.editValid = valid;
}
@@ -259,7 +259,7 @@ public class JFormattedTextField extends JTextField
* @return an Object that <code>text</code> represented
* @throws ParseException if there is an error in the conversion
*/
- public abstract Object stringToValue (String text)
+ public abstract Object stringToValue(String text)
throws ParseException;
/**
@@ -270,7 +270,7 @@ public class JFormattedTextField extends JTextField
* @return a String to be displayed
* @throws ParseException if there is an error in the conversion
*/
- public abstract String valueToString (Object value)
+ public abstract String valueToString(Object value)
throws ParseException;
}
@@ -280,12 +280,12 @@ public class JFormattedTextField extends JTextField
*/
public abstract static class AbstractFormatterFactory
{
- public AbstractFormatterFactory ()
+ public AbstractFormatterFactory()
{
// Do nothing here.
}
- public abstract AbstractFormatter getFormatter (JFormattedTextField tf);
+ public abstract AbstractFormatter getFormatter(JFormattedTextField tf);
}
/** The possible focusLostBehavior options **/
@@ -315,7 +315,7 @@ public class JFormattedTextField extends JTextField
* properly configure this text field to edit a particular type
* of value.
*/
- public JFormattedTextField ()
+ public JFormattedTextField()
{
this((AbstractFormatterFactory) null, null);
}
@@ -328,7 +328,7 @@ public class JFormattedTextField extends JTextField
* @param format the Format that this JFormattedTextField should be able
* to handle
*/
- public JFormattedTextField (Format format)
+ public JFormattedTextField(Format format)
{
this ();
setFormatterFactory(getAppropriateFormatterFactory(format));
@@ -341,9 +341,9 @@ public class JFormattedTextField extends JTextField
*
* @param formatter the formatter to use for this JFormattedTextField
*/
- public JFormattedTextField (AbstractFormatter formatter)
+ public JFormattedTextField(AbstractFormatter formatter)
{
- this(new DefaultFormatterFactory (formatter));
+ this(new DefaultFormatterFactory(formatter));
}
/**
@@ -351,7 +351,7 @@ public class JFormattedTextField extends JTextField
*
* @param factory the formatter factory to use for this JFormattedTextField
*/
- public JFormattedTextField (AbstractFormatterFactory factory)
+ public JFormattedTextField(AbstractFormatterFactory factory)
{
setFormatterFactory(factory);
}
@@ -363,7 +363,7 @@ public class JFormattedTextField extends JTextField
* @param factory the initial formatter factory for this JFormattedTextField
* @param value the initial value for the text field
*/
- public JFormattedTextField (AbstractFormatterFactory factory, Object value)
+ public JFormattedTextField(AbstractFormatterFactory factory, Object value)
{
setFormatterFactory(factory);
setValue(value);
@@ -375,7 +375,7 @@ public class JFormattedTextField extends JTextField
*
* @param value the initial value for this JFormattedTextField
*/
- public JFormattedTextField (Object value)
+ public JFormattedTextField(Object value)
{
setValue(value);
}
@@ -387,13 +387,13 @@ public class JFormattedTextField extends JTextField
* @return a DefaultFormatterFactory whose defaultFormatter is appropriate
* for the given Format.
*/
- private AbstractFormatterFactory getAppropriateFormatterFactory (Format format)
+ private AbstractFormatterFactory getAppropriateFormatterFactory(Format format)
{
AbstractFormatter newFormatter;
if (format instanceof DateFormat)
- newFormatter = new DateFormatter((DateFormat)format);
+ newFormatter = new DateFormatter((DateFormat) format);
else if (format instanceof NumberFormat)
- newFormatter = new NumberFormatter ((NumberFormat)format);
+ newFormatter = new NumberFormatter ((NumberFormat) format);
else
newFormatter = new InternationalFormatter(format);
@@ -406,7 +406,7 @@ public class JFormattedTextField extends JTextField
*
* @throws ParseException if the formatter cannot format the current value
*/
- public void commitEdit ()
+ public void commitEdit()
throws ParseException
{
if (formatter == null)
@@ -427,7 +427,7 @@ public class JFormattedTextField extends JTextField
*
* @return an array of Actions that this text field supports
*/
- public Action[] getActions ()
+ public Action[] getActions()
{
// FIXME: Add JFormattedTextField specific actions
// These are related to committing or cancelling edits.
@@ -449,7 +449,7 @@ public class JFormattedTextField extends JTextField
* Returns the current formatter used for this JFormattedTextField.
* @return the current formatter used for this JFormattedTextField
*/
- public AbstractFormatter getFormatter ()
+ public AbstractFormatter getFormatter()
{
return formatter;
}
@@ -459,12 +459,12 @@ public class JFormattedTextField extends JTextField
* JFormattedTextField.
* @return the factory currently used to generate formatters
*/
- public AbstractFormatterFactory getFormatterFactory ()
+ public AbstractFormatterFactory getFormatterFactory()
{
return formatterFactory;
}
- public String getUIClassID ()
+ public String getUIClassID()
{
return "FormattedTextFieldUI";
}
@@ -475,7 +475,7 @@ public class JFormattedTextField extends JTextField
* valid edits and allows invalid input to be temporarily displayed.
* @return the last committed valid value
*/
- public Object getValue ()
+ public Object getValue()
{
return value;
}
@@ -484,7 +484,7 @@ public class JFormattedTextField extends JTextField
* This method is used to provide feedback to the user when an invalid value
* is input during editing.
*/
- protected void invalidEdit ()
+ protected void invalidEdit()
{
UIManager.getLookAndFeel().provideErrorFeedback(this);
}
@@ -494,7 +494,7 @@ public class JFormattedTextField extends JTextField
* managed by the current formatted.
* @return true if the value being edited is valid.
*/
- public boolean isEditValid ()
+ public boolean isEditValid()
{
return editValid;
}
@@ -506,7 +506,7 @@ public class JFormattedTextField extends JTextField
*
* @param evt the FocusEvent
*/
- protected void processFocusEvent (FocusEvent evt)
+ protected void processFocusEvent(FocusEvent evt)
{
super.processFocusEvent(evt);
// Let the formatterFactory change the formatter for this text field
@@ -561,7 +561,7 @@ public class JFormattedTextField extends JTextField
* @param formatter the AbstractFormatter to use for formatting the value for
* this JFormattedTextField
*/
- protected void setFormatter (AbstractFormatter formatter)
+ protected void setFormatter(AbstractFormatter formatter)
{
AbstractFormatter oldFormatter = null;
@@ -585,7 +585,7 @@ public class JFormattedTextField extends JTextField
* @param factory the AbstractFormatterFactory that will be used to generate
* formatters for this JFormattedTextField
*/
- public void setFormatterFactory (AbstractFormatterFactory factory)
+ public void setFormatterFactory(AbstractFormatterFactory factory)
{
if (formatterFactory == factory)
return;
@@ -606,7 +606,7 @@ public class JFormattedTextField extends JTextField
*
* @param newValue the value to be formatted and displayed
*/
- public void setValue (Object newValue)
+ public void setValue(Object newValue)
{
if (value == newValue)
return;
diff --git a/javax/swing/JFrame.java b/javax/swing/JFrame.java
index d25120560..1371525dd 100644
--- a/javax/swing/JFrame.java
+++ b/javax/swing/JFrame.java
@@ -1,5 +1,5 @@
/* JFrame.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -86,6 +86,8 @@ public class JFrame extends Frame
/**
* A flag for {@link #setDefaultCloseOperation(int)}, indicating that the
* application should be exited, when this <code>JFrame</code> is closed.
+ * Note that in version 1.4, the equivalent constant has been added to
+ * {@link WindowConstants}.
*
* @since 1.3
*/
@@ -93,7 +95,7 @@ public class JFrame extends Frame
private static final long serialVersionUID = -3362141868504252139L;
private static boolean defaultLookAndFeelDecorated;
- private int close_action = HIDE_ON_CLOSE;
+ private int closeAction = HIDE_ON_CLOSE;
protected AccessibleContext accessibleContext;
protected JRootPane rootPane;
@@ -102,12 +104,20 @@ public class JFrame extends Frame
*/
protected boolean rootPaneCheckingEnabled = false;
+ /**
+ * Creates a new frame with an empty string for the title.
+ */
public JFrame()
{
- super("JFrame");
+ super("");
frameInit();
}
+ /**
+ * Creates a new <code>JFrame</code> with the specified title.
+ *
+ * @param title the frame title (<code>null</code> permitted).
+ */
public JFrame(String title)
{
super(title);
@@ -147,7 +157,8 @@ public class JFrame extends Frame
protected void frameInit()
{
- super.setLayout(new BorderLayout(1, 1));
+ super.setLayout(new BorderLayout());
+ setBackground(UIManager.getDefaults().getColor("control"));
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
getRootPane(); // will do set/create
@@ -289,6 +300,12 @@ public class JFrame extends Frame
return defaultLookAndFeelDecorated;
}
+ /**
+ * Returns the object that provides accessibility features for this
+ * <code>JFrame</code>.
+ *
+ * @return The accessible context (an instance of {@link AccessibleJFrame}).
+ */
public AccessibleContext getAccessibleContext()
{
if (accessibleContext == null)
@@ -296,14 +313,39 @@ public class JFrame extends Frame
return accessibleContext;
}
+ /**
+ * Returns a code for the default operation when the frame is closed. The
+ * default value is {@link WindowConstants#HIDE_ON_CLOSE}.
+ *
+ * @return One of: {@link WindowConstants#DO_NOTHING_ON_CLOSE},
+ * {@link WindowConstants#HIDE_ON_CLOSE},
+ * {@link WindowConstants#DISPOSE_ON_CLOSE}, {@link #EXIT_ON_CLOSE}.
+ *
+ * @see #setDefaultCloseOperation(int)
+ */
public int getDefaultCloseOperation()
{
- return close_action;
+ return closeAction;
}
+ /**
+ * Returns a string describing the attributes for the <code>JFrame</code>,
+ * for use in debugging. The return value is guaranteed to be
+ * non-<code>null</code>, but the format may vary between implementations.
+ *
+ * @return A string describing the attributes of the <code>JFrame</code>.
+ */
protected String paramString()
{
- return "JFrame";
+ StringBuffer sb = new StringBuffer(super.paramString());
+ sb.append(",defaultCloseOperation=");
+ sb.append(SwingUtilities.convertWindowConstantToString(
+ getDefaultCloseOperation()));
+ sb.append(",rootPane=");
+ if (rootPane != null)
+ sb.append(rootPane);
+ sb.append(",rootPaneCheckingEnabled=").append(rootPaneCheckingEnabled);
+ return sb.toString();
}
protected void processWindowEvent(WindowEvent e)
@@ -313,7 +355,7 @@ public class JFrame extends Frame
{
case WindowEvent.WINDOW_CLOSING:
{
- switch (close_action)
+ switch (closeAction)
{
case EXIT_ON_CLOSE:
{
@@ -346,17 +388,22 @@ public class JFrame extends Frame
}
/**
- * Defines what happens when this frame is closed. Can be one off
- * <code>EXIT_ON_CLOSE</code>,
- * <code>DISPOSE_ON_CLOSE</code>,
- * <code>HIDE_ON_CLOSE</code> or
- * <code>DO_NOTHING_ON_CLOSE</code>.
- * The default is <code>HIDE_ON_CLOSE</code>.
- * When <code>EXIT_ON_CLOSE</code> is specified this method calls
+ * Sets the default operation that is performed when this frame is closed.
+ * The default is <code>HIDE_ON_CLOSE</code>. When
+ * <code>EXIT_ON_CLOSE</code> is specified this method calls
* <code>SecurityManager.checkExit(0)</code> which might throw a
- * <code>SecurityException</code>. When the specified operation is
- * not one of the above a <code>IllegalArgumentException</code> is
- * thrown.
+ * <code>SecurityException</code>.
+ *
+ * @param operation a code for the operation (one of:
+ * {@link WindowConstants#DO_NOTHING_ON_CLOSE},
+ * {@link WindowConstants#HIDE_ON_CLOSE},
+ * {@link WindowConstants#DISPOSE_ON_CLOSE} and
+ * {@link WindowConstants#EXIT_ON_CLOSE}).
+ *
+ * @throws IllegalArgumentException if <code>operation</code> is not one of
+ * the specified codes.
+ *
+ * @see #getDefaultCloseOperation()
*/
public void setDefaultCloseOperation(int operation)
{
@@ -366,8 +413,9 @@ public class JFrame extends Frame
if (operation != EXIT_ON_CLOSE && operation != DISPOSE_ON_CLOSE
&& operation != HIDE_ON_CLOSE && operation != DO_NOTHING_ON_CLOSE)
- throw new IllegalArgumentException("defaultCloseOperation must be EXIT_ON_CLOSE, HIDE_ON_CLOSE, DISPOSE_ON_CLOSE, or DO_NOTHING_ON_CLOSE");
+ throw new IllegalArgumentException("operation must be EXIT_ON_CLOSE, "
+ + "HIDE_ON_CLOSE, DISPOSE_ON_CLOSE, or DO_NOTHING_ON_CLOSE");
- close_action = operation;
+ closeAction = operation;
}
}
diff --git a/javax/swing/JLabel.java b/javax/swing/JLabel.java
index a993fb8f3..a5fe3ba1a 100644
--- a/javax/swing/JLabel.java
+++ b/javax/swing/JLabel.java
@@ -1,5 +1,5 @@
/* JLabel.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -50,6 +50,7 @@ import java.awt.event.KeyEvent;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleExtendedComponent;
+import javax.accessibility.AccessibleRole;
import javax.accessibility.AccessibleText;
import javax.swing.plaf.LabelUI;
import javax.swing.text.AttributeSet;
@@ -62,12 +63,39 @@ public class JLabel extends JComponent implements Accessible, SwingConstants
{
/**
- * Accessibility support for JLabel.
+ * Provides the accessibility features for the <code>JLabel</code>
+ * component.
*/
protected class AccessibleJLabel
extends JComponent.AccessibleJComponent
implements AccessibleText, AccessibleExtendedComponent
{
+
+ /**
+ * Returns the accessible name.
+ *
+ * @return The accessible name.
+ */
+ public String getAccessibleName()
+ {
+ if (accessibleName != null)
+ return accessibleName;
+ if (text != null)
+ return text;
+ else
+ return super.getAccessibleName();
+ }
+
+ /**
+ * Returns the accessible role for the <code>JLabel</code> component.
+ *
+ * @return {@link AccessibleRole#LABEL}.
+ */
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.LABEL;
+ }
+
/**
* Returns the selected text. This is null since JLabels
* are not selectable.
@@ -297,7 +325,6 @@ public class JLabel extends JComponent implements Accessible, SwingConstants
}
}
- /** DOCUMENT ME! */
private static final long serialVersionUID = 5496508283662221534L;
static final String LABEL_PROPERTY = "labeledBy";
@@ -452,14 +479,42 @@ public class JLabel extends JComponent implements Accessible, SwingConstants
}
/**
- * This method is used primarily for debugging purposes and returns a string
- * that can be used to represent this label.
+ * Returns a string describing the attributes for the <code>JLabel</code>
+ * component, for use in debugging. The return value is guaranteed to be
+ * non-<code>null</code>, but the format of the string may vary between
+ * implementations.
*
- * @return A string to represent this label.
+ * @return A string describing the attributes of the <code>JLabel</code>.
*/
protected String paramString()
{
- return super.paramString();
+ StringBuffer sb = new StringBuffer(super.paramString());
+ sb.append(",defaultIcon=");
+ if (icon != null)
+ sb.append(icon);
+ sb.append(",disabledIcon=");
+ if (disabledIcon != null)
+ sb.append(disabledIcon);
+ sb.append(",horizontalAlignment=");
+ sb.append(SwingUtilities.convertHorizontalAlignmentCodeToString(
+ horizontalAlignment));
+ sb.append(",horizontalTextPosition=");
+ sb.append(SwingUtilities.convertHorizontalAlignmentCodeToString(
+ horizontalTextPosition));
+ sb.append(",iconTextGap=").append(iconTextGap);
+ sb.append(",labelFor=");
+ if (labelFor != null)
+ sb.append(labelFor);
+ sb.append(",text=");
+ if (text != null)
+ sb.append(text);
+ sb.append(",verticalAlignment=");
+ sb.append(SwingUtilities.convertVerticalAlignmentCodeToString(
+ verticalAlignment));
+ sb.append(",verticalTextPosition=");
+ sb.append(SwingUtilities.convertVerticalAlignmentCodeToString(
+ verticalTextPosition));
+ return sb.toString();
}
/**
@@ -868,24 +923,25 @@ public class JLabel extends JComponent implements Accessible, SwingConstants
{
if (c != labelFor)
{
+ Component oldLabelFor = labelFor;
+ labelFor = c;
+ firePropertyChange("labelFor", oldLabelFor, labelFor);
+
// We put the label into the client properties for the labeled
// component so that it can be read by the AccessibleJComponent.
// The other option would be to reserve a default visible field
- // in JComponent, but since this is relativly seldomly used, it
+ // in JComponent, but since this is relatively seldomly used, it
// would be unnecessary waste of memory to do so.
- Component oldLabelFor = labelFor;
if (oldLabelFor instanceof JComponent)
{
((JComponent) oldLabelFor).putClientProperty(LABEL_PROPERTY, null);
}
- labelFor = c;
- if (labelFor instanceof JComponent)
+ if (labelFor instanceof JComponent)
{
((JComponent) labelFor).putClientProperty(LABEL_PROPERTY, this);
}
- firePropertyChange("labelFor", oldLabelFor, labelFor);
}
}
@@ -902,9 +958,10 @@ public class JLabel extends JComponent implements Accessible, SwingConstants
}
/**
- * DOCUMENT ME!
+ * Returns the object that provides accessibility features for this
+ * <code>JLabel</code> component.
*
- * @return The accessible context.
+ * @return The accessible context (an instance of {@link AccessibleJLabel}).
*/
public AccessibleContext getAccessibleContext()
{
diff --git a/javax/swing/JLayeredPane.java b/javax/swing/JLayeredPane.java
index f887c2450..11650e721 100644
--- a/javax/swing/JLayeredPane.java
+++ b/javax/swing/JLayeredPane.java
@@ -147,19 +147,19 @@ public class JLayeredPane extends JComponent implements Accessible
public static final String LAYER_PROPERTY = "layeredContainerLayer";
- public static final Integer FRAME_CONTENT_LAYER = new Integer (-30000);
+ public static final Integer FRAME_CONTENT_LAYER = new Integer(-30000);
- public static final Integer DEFAULT_LAYER = new Integer (0);
- public static final Integer PALETTE_LAYER = new Integer (100);
- public static final Integer MODAL_LAYER = new Integer (200);
- public static final Integer POPUP_LAYER = new Integer (300);
- public static final Integer DRAG_LAYER = new Integer (400);
+ public static final Integer DEFAULT_LAYER = new Integer(0);
+ public static final Integer PALETTE_LAYER = new Integer(100);
+ public static final Integer MODAL_LAYER = new Integer(200);
+ public static final Integer POPUP_LAYER = new Integer(300);
+ public static final Integer DRAG_LAYER = new Integer(400);
private Hashtable componentToLayer; // Component -> Layer Number (Integer)
public JLayeredPane()
{
- componentToLayer = new Hashtable ();
+ componentToLayer = new Hashtable();
setLayout(null);
}
diff --git a/javax/swing/JList.java b/javax/swing/JList.java
index 55978a4c6..eab6be3c3 100644
--- a/javax/swing/JList.java
+++ b/javax/swing/JList.java
@@ -1475,19 +1475,18 @@ public class JList extends JComponent implements Accessible, Scrollable
}
/**
- * Returns all the values in the list's {@link #model} property which
- * are selected, according to the list's {@link #selectionModel} property.
- *
+ * Returns all the values in the list's {@link #model} property which are
+ * selected, according to the list's {@link #selectionModel} property.
+ *
* @return An array containing all the selected values
- *
* @see #setSelectedValue
*/
public Object[] getSelectedValues()
{
- int [] idx = getSelectedIndices();
- Object [] v = new Object[idx.length];
+ int[] idx = getSelectedIndices();
+ Object[] v = new Object[idx.length];
for (int i = 0; i < idx.length; ++i)
- v[i] = getModel().getElementAt(i);
+ v[i] = getModel().getElementAt(idx[i]);
return v;
}
diff --git a/javax/swing/JMenu.java b/javax/swing/JMenu.java
index 37ed14854..02cb20eab 100644
--- a/javax/swing/JMenu.java
+++ b/javax/swing/JMenu.java
@@ -38,8 +38,6 @@ exception statement from your version. */
package javax.swing;
-import gnu.classpath.NotImplementedException;
-
import java.awt.Component;
import java.awt.Point;
import java.awt.event.KeyEvent;
@@ -48,6 +46,7 @@ import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.Serializable;
+import java.util.ArrayList;
import java.util.EventListener;
import javax.accessibility.Accessible;
@@ -811,7 +810,9 @@ public class JMenu extends JMenuItem implements Accessible, MenuElement
return accessibleContext;
}
- // FIXME: This inner class is a complete stub and needs to be implemented.
+ /**
+ * Implements support for assisitive technologies for <code>JMenu</code>.
+ */
protected class AccessibleJMenu extends AccessibleJMenuItem
implements AccessibleSelection
{
@@ -822,69 +823,245 @@ public class JMenu extends JMenuItem implements Accessible, MenuElement
// Nothing to do here.
}
+ /**
+ * Returns the number of accessible children of this object.
+ *
+ * @return the number of accessible children of this object
+ */
public int getAccessibleChildrenCount()
- throws NotImplementedException
{
- return 0;
+ Component[] children = getMenuComponents();
+ int count = 0;
+ for (int i = 0; i < children.length; i++)
+ {
+ if (children[i] instanceof Accessible)
+ count++;
+ }
+ return count;
}
- public Accessible getAccessibleChild(int value0)
- throws NotImplementedException
+ /**
+ * Returns the accessible child with the specified <code>index</code>.
+ *
+ * @param index the index of the child to fetch
+ *
+ * @return the accessible child with the specified <code>index</code>
+ */
+ public Accessible getAccessibleChild(int index)
{
- return null;
+ Component[] children = getMenuComponents();
+ int count = 0;
+ Accessible found = null;
+ for (int i = 0; i < children.length; i++)
+ {
+ if (children[i] instanceof Accessible)
+ {
+ if (count == index)
+ {
+ found = (Accessible) children[i];
+ break;
+ }
+ count++;
+ }
+ }
+ return found;
}
+ /**
+ * Returns the accessible selection of this object. AccessibleJMenus handle
+ * their selection themselves, so we always return <code>this</code> here.
+ *
+ * @return the accessible selection of this object
+ */
public AccessibleSelection getAccessibleSelection()
- throws NotImplementedException
{
- return null;
+ return this;
}
- public Accessible getAccessibleSelection(int value0)
- throws NotImplementedException
+ /**
+ * Returns the selected accessible child with the specified
+ * <code>index</code>.
+ *
+ * @param index the index of the accessible selected child to return
+ *
+ * @return the selected accessible child with the specified
+ * <code>index</code>
+ */
+ public Accessible getAccessibleSelection(int index)
{
- return null;
+ Accessible selected = null;
+ // Only one item can be selected, which must therefore have index == 0.
+ if (index == 0)
+ {
+ MenuSelectionManager msm = MenuSelectionManager.defaultManager();
+ MenuElement[] me = msm.getSelectedPath();
+ if (me != null)
+ {
+ for (int i = 0; i < me.length; i++)
+ {
+ if (me[i] == JMenu.this)
+ {
+ // This JMenu is selected, find and return the next
+ // JMenuItem in the path.
+ do
+ {
+ if (me[i] instanceof Accessible)
+ {
+ selected = (Accessible) me[i];
+ break;
+ }
+ i++;
+ } while (i < me.length);
+ }
+ if (selected != null)
+ break;
+ }
+ }
+ }
+ return selected;
}
- public boolean isAccessibleChildSelected(int value0)
- throws NotImplementedException
+ /**
+ * Returns <code>true</code> if the accessible child with the specified
+ * index is selected, <code>false</code> otherwise.
+ *
+ * @param index the index of the accessible child to check
+ *
+ * @return <code>true</code> if the accessible child with the specified
+ * index is selected, <code>false</code> otherwise
+ */
+ public boolean isAccessibleChildSelected(int index)
{
- return false;
+ boolean selected = false;
+ MenuSelectionManager msm = MenuSelectionManager.defaultManager();
+ MenuElement[] me = msm.getSelectedPath();
+ if (me != null)
+ {
+ Accessible toBeFound = getAccessibleChild(index);
+ for (int i = 0; i < me.length; i++)
+ {
+ if (me[i] == toBeFound)
+ {
+ selected = true;
+ break;
+ }
+ }
+ }
+ return selected;
}
+ /**
+ * Returns the accessible role of this object, which is
+ * {@link AccessibleRole#MENU} for the AccessibleJMenu.
+ *
+ * @return the accessible role of this object
+ */
public AccessibleRole getAccessibleRole()
{
return AccessibleRole.MENU;
}
+ /**
+ * Returns the number of selected accessible children. This will be
+ * <code>0</code> if no item is selected, or <code>1</code> if an item
+ * is selected. AccessibleJMenu can have maximum 1 selected item.
+ *
+ * @return the number of selected accessible children
+ */
public int getAccessibleSelectionCount()
- throws NotImplementedException
{
- return 0;
+ int count = 0;
+ MenuSelectionManager msm = MenuSelectionManager.defaultManager();
+ MenuElement[] me = msm.getSelectedPath();
+ if (me != null)
+ {
+ for (int i = 0; i < me.length; i++)
+ {
+ if (me[i] == JMenu.this)
+ {
+ if (i + 1 < me.length)
+ {
+ count = 1;
+ break;
+ }
+ }
+ }
+ }
+ return count;
}
- public void addAccessibleSelection(int value0)
- throws NotImplementedException
+ /**
+ * Selects the accessible child with the specified index.
+ *
+ * @param index the index of the accessible child to select
+ */
+ public void addAccessibleSelection(int index)
{
- // TODO: Implement this properly.
+ Accessible child = getAccessibleChild(index);
+ if (child != null && child instanceof JMenuItem)
+ {
+ JMenuItem mi = (JMenuItem) child;
+ MenuSelectionManager msm = MenuSelectionManager.defaultManager();
+ msm.setSelectedPath(createPath(JMenu.this));
+ }
}
- public void removeAccessibleSelection(int value0)
- throws NotImplementedException
+ /**
+ * Removes the item with the specified index from the selection.
+ *
+ * @param index the index of the selected item to remove from the selection
+ */
+ public void removeAccessibleSelection(int index)
{
- // TODO: Implement this properly.
+ Accessible child = getAccessibleChild(index);
+ if (child != null)
+ {
+ MenuSelectionManager msm = MenuSelectionManager.defaultManager();
+ MenuElement[] oldSelection = msm.getSelectedPath();
+ for (int i = 0; i < oldSelection.length; i++)
+ {
+ if (oldSelection[i] == child)
+ {
+ // Found the specified child in the selection. Remove it
+ // from the selection.
+ MenuElement[] newSel = new MenuElement[i - 1];
+ System.arraycopy(oldSelection, 0, newSel, 0, i - 1);
+ msm.setSelectedPath(newSel);
+ break;
+ }
+ }
+ }
}
+ /**
+ * Removes all possibly selected accessible children of this object from
+ * the selection.
+ */
public void clearAccessibleSelection()
- throws NotImplementedException
{
- // TODO: Implement this properly.
+ MenuSelectionManager msm = MenuSelectionManager.defaultManager();
+ MenuElement[] oldSelection = msm.getSelectedPath();
+ for (int i = 0; i < oldSelection.length; i++)
+ {
+ if (oldSelection[i] == JMenu.this)
+ {
+ // Found this menu in the selection. Remove all children from
+ // the selection.
+ MenuElement[] newSel = new MenuElement[i];
+ System.arraycopy(oldSelection, 0, newSel, 0, i);
+ msm.setSelectedPath(newSel);
+ break;
+ }
+ }
}
+ /**
+ * AccessibleJMenu don't support multiple selection, so this method
+ * does nothing.
+ */
public void selectAllAccessibleSelection()
- throws NotImplementedException
{
- // TODO: Implement this properly.
+ // Nothing to do here.
}
}
@@ -939,4 +1116,44 @@ public class JMenu extends JMenuItem implements Accessible, MenuElement
}
}
+ /**
+ * Creates an array to be feeded as argument to
+ * {@link MenuSelectionManager#setSelectedPath(MenuElement[])} for the
+ * specified element. This has the effect of selecting the specified element
+ * and all its parents.
+ *
+ * @param leaf the leaf element for which to create the selected path
+ *
+ * @return the selected path array
+ */
+ MenuElement[] createPath(JMenu leaf)
+ {
+ ArrayList path = new ArrayList();
+ MenuElement[] array = null;
+ Component current = leaf.getPopupMenu();
+ while (true)
+ {
+ if (current instanceof JPopupMenu)
+ {
+ JPopupMenu popupMenu = (JPopupMenu) current;
+ path.add(0, popupMenu);
+ current = popupMenu.getInvoker();
+ }
+ else if (current instanceof JMenu)
+ {
+ JMenu menu = (JMenu) current;
+ path.add(0, menu);
+ current = menu.getParent();
+ }
+ else if (current instanceof JMenuBar)
+ {
+ JMenuBar menuBar = (JMenuBar) current;
+ path.add(0, menuBar);
+ array = new MenuElement[path.size()];
+ array = (MenuElement[]) path.toArray(array);
+ break;
+ }
+ }
+ return array;
+ }
}
diff --git a/javax/swing/JMenuItem.java b/javax/swing/JMenuItem.java
index 272c1cfe6..90d54b1d3 100644
--- a/javax/swing/JMenuItem.java
+++ b/javax/swing/JMenuItem.java
@@ -38,8 +38,6 @@ exception statement from your version. */
package javax.swing;
-import gnu.classpath.NotImplementedException;
-
import java.awt.Component;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
@@ -51,6 +49,7 @@ import java.util.EventListener;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleState;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.MenuDragMouseEvent;
@@ -673,7 +672,7 @@ public class JMenuItem extends AbstractButton implements Accessible,
}
/**
- * Returns a string describing the attributes for the <code>JToolTip</code>
+ * Returns a string describing the attributes for the <code>JMenuItem</code>
* component, for use in debugging. The return value is guaranteed to be
* non-<code>null</code>, but the format of the string may vary between
* implementations.
@@ -696,7 +695,11 @@ public class JMenuItem extends AbstractButton implements Accessible,
public AccessibleContext getAccessibleContext()
{
if (accessibleContext == null)
- accessibleContext = new AccessibleJMenuItem();
+ {
+ AccessibleJMenuItem ctx = new AccessibleJMenuItem();
+ addChangeListener(ctx);
+ accessibleContext = ctx;
+ }
return accessibleContext;
}
@@ -712,6 +715,11 @@ public class JMenuItem extends AbstractButton implements Accessible,
{
private static final long serialVersionUID = 6748924232082076534L;
+ private boolean armed;
+ private boolean focusOwner;
+ private boolean pressed;
+ private boolean selected;
+
/**
* Creates a new <code>AccessibleJMenuItem</code> instance.
*/
@@ -720,10 +728,99 @@ public class JMenuItem extends AbstractButton implements Accessible,
//super(component);
}
+ /**
+ * Receives notification when the menu item's state changes and fires
+ * appropriate property change events to registered listeners.
+ *
+ * @param event the change event
+ */
public void stateChanged(ChangeEvent event)
- throws NotImplementedException
{
- // TODO: What should be done here, if anything?
+ // This is fired in all cases.
+ firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
+ Boolean.FALSE, Boolean.TRUE);
+
+ ButtonModel model = getModel();
+
+ // Handle the armed property.
+ if (model.isArmed())
+ {
+ if (! armed)
+ {
+ armed = true;
+ firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
+ AccessibleState.ARMED, null);
+ }
+ }
+ else
+ {
+ if (armed)
+ {
+ armed = false;
+ firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
+ null, AccessibleState.ARMED);
+ }
+ }
+
+ // Handle the pressed property.
+ if (model.isPressed())
+ {
+ if (! pressed)
+ {
+ pressed = true;
+ firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
+ AccessibleState.PRESSED, null);
+ }
+ }
+ else
+ {
+ if (pressed)
+ {
+ pressed = false;
+ firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
+ null, AccessibleState.PRESSED);
+ }
+ }
+
+ // Handle the selected property.
+ if (model.isSelected())
+ {
+ if (! selected)
+ {
+ selected = true;
+ firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
+ AccessibleState.SELECTED, null);
+ }
+ }
+ else
+ {
+ if (selected)
+ {
+ selected = false;
+ firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
+ null, AccessibleState.SELECTED);
+ }
+ }
+
+ // Handle the focusOwner property.
+ if (isFocusOwner())
+ {
+ if (! focusOwner)
+ {
+ focusOwner = true;
+ firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
+ AccessibleState.FOCUSED, null);
+ }
+ }
+ else
+ {
+ if (focusOwner)
+ {
+ focusOwner = false;
+ firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
+ null, AccessibleState.FOCUSED);
+ }
+ }
}
/**
diff --git a/javax/swing/JOptionPane.java b/javax/swing/JOptionPane.java
index 36f4a867d..f94905538 100644
--- a/javax/swing/JOptionPane.java
+++ b/javax/swing/JOptionPane.java
@@ -38,14 +38,20 @@ exception statement from your version. */
package javax.swing;
+import java.awt.AWTEvent;
+import java.awt.ActiveEvent;
import java.awt.Component;
+import java.awt.Container;
+import java.awt.EventQueue;
import java.awt.Frame;
+import java.awt.MenuComponent;
+import java.awt.Toolkit;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseMotionAdapter;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
-import javax.swing.event.InternalFrameAdapter;
-import javax.swing.event.InternalFrameEvent;
import javax.swing.plaf.OptionPaneUI;
/**
@@ -1528,31 +1534,64 @@ public class JOptionPane extends JComponent implements Accessible
*/
private static void startModal(JInternalFrame f)
{
- synchronized (f)
- {
- final JInternalFrame tmp = f;
- tmp.toFront();
-
- f.addInternalFrameListener(new InternalFrameAdapter()
- {
- public void internalFrameClosed(InternalFrameEvent e)
- {
- synchronized (tmp)
- {
- tmp.removeInternalFrameListener(this);
- tmp.notifyAll();
- }
- }
- });
- try
- {
- while (! f.isClosed())
- f.wait();
- }
- catch (InterruptedException ignored)
- {
- // Ignore this Exception.
- }
- }
+ // We need to add an additional glasspane-like component directly
+ // below the frame, which intercepts all mouse events that are not
+ // directed at the frame itself.
+ JPanel modalInterceptor = new JPanel();
+ modalInterceptor.setOpaque(false);
+ JLayeredPane lp = JLayeredPane.getLayeredPaneAbove(f);
+ lp.setLayer(modalInterceptor, JLayeredPane.MODAL_LAYER.intValue());
+ modalInterceptor.setBounds(0, 0, lp.getWidth(), lp.getHeight());
+ modalInterceptor.addMouseListener(new MouseAdapter(){});
+ modalInterceptor.addMouseMotionListener(new MouseMotionAdapter(){});
+ lp.add(modalInterceptor);
+ f.toFront();
+
+ // We need to explicitly dispatch events when we are blocking the event
+ // dispatch thread.
+ EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue();
+ try
+ {
+ while (! f.isClosed())
+ {
+ if (EventQueue.isDispatchThread())
+ {
+ // The getNextEventMethod() issues wait() when no
+ // event is available, so we don't need do explicitly wait().
+ AWTEvent ev = queue.getNextEvent();
+ // This mimics EventQueue.dispatchEvent(). We can't use
+ // EventQueue.dispatchEvent() directly, because it is
+ // protected, unfortunately.
+ if (ev instanceof ActiveEvent)
+ ((ActiveEvent) ev).dispatch();
+ else if (ev.getSource() instanceof Component)
+ ((Component) ev.getSource()).dispatchEvent(ev);
+ else if (ev.getSource() instanceof MenuComponent)
+ ((MenuComponent) ev.getSource()).dispatchEvent(ev);
+ // Other events are ignored as per spec in
+ // EventQueue.dispatchEvent
+ }
+ else
+ {
+ // Give other threads a chance to become active.
+ Thread.yield();
+ }
+ }
+ }
+ catch (InterruptedException ex)
+ {
+ // If we get interrupted, then leave the modal state.
+ }
+ finally
+ {
+ // Clean up the modal interceptor.
+ lp.remove(modalInterceptor);
+
+ // Remove the internal frame from its parent, so it is no longer
+ // lurking around and clogging memory.
+ Container parent = f.getParent();
+ if (parent != null)
+ parent.remove(f);
+ }
}
}
diff --git a/javax/swing/JPopupMenu.java b/javax/swing/JPopupMenu.java
index a54bd777f..c7890ea0e 100644
--- a/javax/swing/JPopupMenu.java
+++ b/javax/swing/JPopupMenu.java
@@ -52,6 +52,7 @@ import java.util.EventListener;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
+import javax.swing.event.MenuKeyListener;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.plaf.PopupMenuUI;
@@ -410,6 +411,36 @@ public class JPopupMenu extends JComponent implements Accessible, MenuElement
}
/**
+ * Adds a MenuKeyListener to the popup.
+ *
+ * @param l - the listener to add.
+ */
+ public void addMenuKeyListener(MenuKeyListener l)
+ {
+ listenerList.add(MenuKeyListener.class, l);
+ }
+
+ /**
+ * Removes a MenuKeyListener from the popup.
+ *
+ * @param l - the listener to remove.
+ */
+ public void removeMenuKeyListener(MenuKeyListener l)
+ {
+ listenerList.remove(MenuKeyListener.class, l);
+ }
+
+ /**
+ * Returns array of getMenuKeyListeners that are listening to JPopupMenu.
+ *
+ * @return array of getMenuKeyListeners that are listening to JPopupMenu
+ */
+ public MenuKeyListener[] getMenuKeyListeners()
+ {
+ return ((MenuKeyListener[]) listenerList.getListeners(MenuKeyListener.class));
+ }
+
+ /**
* Adds popupMenuListener to listen for PopupMenuEvents fired
* by the JPopupMenu
*
diff --git a/javax/swing/JProgressBar.java b/javax/swing/JProgressBar.java
index db936f64a..ed2d0088d 100644
--- a/javax/swing/JProgressBar.java
+++ b/javax/swing/JProgressBar.java
@@ -53,15 +53,14 @@ import javax.swing.event.ChangeListener;
import javax.swing.plaf.ProgressBarUI;
/**
- * The ProgressBar is a widget that displays in two modes. In
- * determinate mode, it displays fills a percentage of its bar
- * based on its current value. In indeterminate mode, it creates
- * box and bounces it between its bounds.
- *
+ * A component that displays a visual indicator of the progress of a task. The
+ * component has two modes: determinate and indeterminate. In determinate mode,
+ * the <code>JProgressBar</code> fills a percentage of its bar based on its
+ * current value. In indeterminate mode, it creates box and bounces it between
+ * its bounds.
* <p>
- * JProgressBars have the following properties:
+ * This component has the following properties:
* </p>
- *
* <table>
* <tr><th> Property </th><th> Stored in </th><th> Bound? </th></tr>
* <tr><td> borderPainted </td><td> progressBar </td><td> yes </td></tr>
@@ -193,33 +192,67 @@ public class JProgressBar extends JComponent implements SwingConstants,
private static final long serialVersionUID = 1980046021813598781L;
- /** Whether the ProgressBar is determinate. */
+ /**
+ * A flag that determines the mode (<code>true</code> for indeterminate,
+ * <code>false</code> for determinate).
+ */
private transient boolean indeterminate = false;
- /** The orientation of the ProgressBar. Always set by constructor. */
+ /**
+ * The orientation of the <code>JProgressBar</code>
+ * ({@link SwingConstants#HORIZONTAL} or {@link SwingConstants#VERTICAL}).
+ * Defaults to {@link SwingConstants#HORIZONTAL}.
+ * @see #setOrientation(int)
+ */
protected int orientation;
- /** Whether borders should be painted. */
+ /**
+ * A flag the controls whether or not the component's border is painted.
+ * The default is <code>true</code>.
+ * @see #setBorderPainted(boolean)
+ */
protected boolean paintBorder = true;
- /** The model describing this ProgressBar. */
+ /**
+ * The model defining the bounds and current value for the progress bar.
+ * @see #setModel(BoundedRangeModel)
+ */
protected BoundedRangeModel model;
- /** The string that is displayed by the ProgressBar. */
+ /**
+ * A custom string for display in the progress bar. If this is
+ * <code>null</code>, a default string will be generated.
+ * @see #setString(String)
+ */
protected String progressString;
- /** Whether the string should be painted. */
+ /**
+ * A flag that controls whether a string is displayed within the progress
+ * bar.
+ * @see #setStringPainted(boolean)
+ */
protected boolean paintString = false;
- /** The static changeEvent passed to all ChangeListeners. */
+ /**
+ * A single change event reused for all events.
+ * @see #fireStateChanged()
+ */
protected transient ChangeEvent changeEvent;
- /** The ChangeListener that listens to the model. */
+ /**
+ * The listener that is registered with the model. */
protected ChangeListener changeListener;
/**
- * Creates a new horizontally oriented JProgressBar object
- * with a minimum of 0 and a maximum of 100.
+ * Creates a new <code>JProgressBar</code> with default attributes. The
+ * following defaults are used:
+ * <p>
+ * <ul>
+ * <li><code>value</code>: 0;</li>
+ * <li><code>minimum</code>: 0;</li>
+ * <li><code>maximum</code>: 100;</li>
+ * <li><code>orientation</code>: {@link SwingConstants#HORIZONTAL}.</li>
+ * </ul>
*/
public JProgressBar()
{
@@ -227,13 +260,20 @@ public class JProgressBar extends JComponent implements SwingConstants,
}
/**
- * Creates a new JProgressBar object with a minimum of 0,
- * a maximum of 100, and the given orientation.
- *
- * @param orientation The orientation of the JProgressBar.
+ * Creates a new <code>JProgressBar</code> with the specified
+ * <code>orientation</code>. The following defaults are used:
+ * <p>
+ * <ul>
+ * <li><code>value</code>: 0;</li>
+ * <li><code>minimum</code>: 0;</li>
+ * <li><code>maximum</code>: 100;</li>
+ * </ul>
*
- * @throws IllegalArgumentException if <code>orientation</code> is not either
- * {@link #HORIZONTAL} or {@link #VERTICAL}.
+ * @param orientation the orientation ({@link #HORIZONTAL} or
+ * {@link #VERTICAL}).
+ *
+ * @throws IllegalArgumentException if <code>orientation</code> is not one of
+ * the specified values.
*/
public JProgressBar(int orientation)
{
@@ -241,11 +281,16 @@ public class JProgressBar extends JComponent implements SwingConstants,
}
/**
- * Creates a new horizontally oriented JProgressBar object
- * with the given minimum and maximum.
- *
- * @param minimum The minimum of the JProgressBar.
- * @param maximum The maximum of the JProgressBar.
+ * Creates a new <code>JProgressBar</code> with the specified value range.
+ * The following defaults are used:
+ * <p>
+ * <ul>
+ * <li><code>value</code>: <code>minimum</code>;</li>
+ * <li><code>orientation</code>: {@link SwingConstants#HORIZONTAL}.</li>
+ * </ul>
+ *
+ * @param minimum the lower bound of the value range.
+ * @param maximum the upper bound of the value range.
*/
public JProgressBar(int minimum, int maximum)
{
@@ -253,15 +298,20 @@ public class JProgressBar extends JComponent implements SwingConstants,
}
/**
- * Creates a new JProgressBar object with the given minimum,
- * maximum, and orientation.
- *
- * @param minimum The minimum of the JProgressBar.
- * @param maximum The maximum of the JProgressBar.
- * @param orientation The orientation of the JProgressBar.
+ * Creates a new <code>JProgressBar</code> with the specified range and
+ * orientation. The following defaults are used:
+ * <p>
+ * <ul>
+ * <li><code>value</code>: <code>minimum</code>;</li>
+ * </ul>
+ *
+ * @param minimum the lower bound of the value range.
+ * @param maximum the upper bound of the value range.
+ * @param orientation the orientation ({@link #HORIZONTAL} or
+ * {@link #VERTICAL}).
*
- * @throws IllegalArgumentException if <code>orientation</code> is not either
- * {@link #HORIZONTAL} or {@link #VERTICAL}.
+ * @throws IllegalArgumentException if <code>orientation</code> is not one of
+ * the specified values.
*/
public JProgressBar(int orientation, int minimum, int maximum)
{
@@ -276,10 +326,14 @@ public class JProgressBar extends JComponent implements SwingConstants,
}
/**
- * Creates a new horizontally oriented JProgressBar object
- * with the given model.
- *
- * @param model The model to be used with the JProgressBar.
+ * Creates a new <code>JProgressBar</code> with the specified model. The
+ * following defaults are used:
+ * <p>
+ * <ul>
+ * <li><code>orientation</code>: {@link SwingConstants#HORIZONTAL}.</li>
+ * </ul>
+ *
+ * @param model the model (<code>null</code> not permitted).
*/
public JProgressBar(BoundedRangeModel model)
{
@@ -291,9 +345,12 @@ public class JProgressBar extends JComponent implements SwingConstants,
}
/**
- * This method returns the current value of the JProgressBar.
+ * Returns the current value for the <code>JProgressBar</code>. This value
+ * is fetched from the model.
*
- * @return The current value of the JProgressBar.
+ * @return The current value.
+ *
+ * @see #setValue(int)
*/
public int getValue()
{
@@ -301,9 +358,20 @@ public class JProgressBar extends JComponent implements SwingConstants,
}
/**
- * This method sets the value of the JProgressBar.
+ * Sets the current value for the <code>JProgressBar</code>. The value is
+ * stored in the component's <code>model</code> (see {@link #getModel()}).
+ * If the new value is different to the old value, a {@link ChangeEvent} is
+ * sent to the model's registered listeners. In turn, this triggers a call
+ * to {@link #fireStateChanged()} which will send a <code>ChangeEvent</code>
+ * to this component's registered listeners.
+ * <p>
+ * If <code>value</code> is outside the range <code>minimum</code> to
+ * <code>maximum</code>, it will be set to the nearest of those boundary
+ * values.
*
- * @param value The value of the JProgressBar.
+ * @param value the new value.
+ *
+ * @see #getValue()
*/
public void setValue(int value)
{
@@ -311,23 +379,29 @@ public class JProgressBar extends JComponent implements SwingConstants,
}
/**
- * This method paints the border of the JProgressBar
+ * Paints the component's border, but only if {@link #isBorderPainted()}
+ * returns <code>true</code>.
*
- * @param graphics The graphics object to paint with.
+ * @param graphics the graphics object to paint with.
+ *
+ * @see #setBorderPainted(boolean)
*/
protected void paintBorder(Graphics graphics)
{
Border border = getBorder();
if (paintBorder && border != null)
- border.paintBorder(this, graphics, 0, 0,
- getWidth(),
- getHeight());
+ border.paintBorder(this, graphics, 0, 0, getWidth(), getHeight());
}
/**
- * This method returns the orientation of the JProgressBar.
+ * Returns the orientation of the <code>JProgressBar</code> component, which
+ * is either {@link SwingConstants#HORIZONTAL} or
+ * {@link SwingConstants#VERTICAL}. The default orientation is
+ * <code>HORIZONTAL</code>.
*
- * @return The orientation of the JProgressBar.
+ * @return The orientation.
+ *
+ * @see #setOrientation(int)
*/
public int getOrientation()
{
@@ -335,12 +409,17 @@ public class JProgressBar extends JComponent implements SwingConstants,
}
/**
- * This method changes the orientation property. The orientation of the
- * JProgressBar can be either horizontal or vertical.
+ * Sets the orientation for this <code>JProgressBar</code> component and,
+ * if the value changes, sends a {@link PropertyChangeEvent} (with the
+ * property name <code>"orientation"</code>) to all registered listeners.
*
- * @param orientation The orientation of the JProgressBar.
+ * @param orientation the orientation ({@link #HORIZONTAL} or
+ * {@link #VERTICAL}).
+ *
* @throws IllegalArgumentException if <code>orientation</code> is not
- * either {@link #HORIZONTAL} or {@link #VERTICAL}.
+ * one of the listed values.
+ *
+ * @see #getOrientation()
*/
public void setOrientation(int orientation)
{
@@ -349,17 +428,21 @@ public class JProgressBar extends JComponent implements SwingConstants,
+ " is not a legal orientation");
if (this.orientation != orientation)
{
- int oldOrientation = this.orientation;
- this.orientation = orientation;
- firePropertyChange("orientation", oldOrientation,
- this.orientation);
+ int oldOrientation = this.orientation;
+ this.orientation = orientation;
+ firePropertyChange("orientation", oldOrientation, this.orientation);
}
}
/**
- * This method returns whether the progressString will be painted.
+ * Returns the flag that controls whether or not the string returned by
+ * {@link #getString()} is displayed by the <code>JProgressBar</code>
+ * component.
*
- * @return Whether the string is painted.
+ * @return <code>true</code> if the string should be displayed, and
+ * <code>false</code> otherwise.
+ *
+ * @see #setStringPainted(boolean)
*/
public boolean isStringPainted()
{
@@ -367,28 +450,37 @@ public class JProgressBar extends JComponent implements SwingConstants,
}
/**
- * This method changes the stringPainted property.
+ * Sets the flag that controls whether or not the string returned by
+ * {@link #getString()} is displayed by the <code>JProgressBar</code>
+ * component. If the flag value changes, a {@link PropertyChangeEvent} (with
+ * the property name <code>"stringPainted"</code>) is sent to all registered
+ * listeners.
*
- * @param painted Whether the string is painted.
+ * @param painted the new flag value.
+ *
+ * @see #isStringPainted()
+ * @see #setString(String)
*/
public void setStringPainted(boolean painted)
{
if (paintString != painted)
{
- boolean oldPainted = paintString;
- paintString = painted;
- firePropertyChange("stringPainted", oldPainted,
- paintString);
+ boolean oldPainted = paintString;
+ paintString = painted;
+ firePropertyChange("stringPainted", oldPainted, paintString);
}
}
/**
- * This method returns the string that is painted if the
- * stringPainted property is set to true. If there is no
- * string set, it will return a string containing the
- * JProgressBar's value as a percent.
+ * Returns the string that is painted on the <code>JProgressBar</code> if
+ * {@link #isStringPainted()} returns <code>true</code>. If no string has
+ * been explicitly set, this method will return a string displaying the
+ * value of {@link #getPercentComplete()}.
*
- * @return The string that is painted.
+ * @return The string.
+ *
+ * @see #setString(String)
+ * @see #setStringPainted(boolean)
*/
public String getString()
{
@@ -399,12 +491,16 @@ public class JProgressBar extends JComponent implements SwingConstants,
}
/**
- * This method changes the string property. The string
- * given will be the one painted. If you want to
- * revert to the default string given, set the
- * string to null.
+ * Sets the string to display within the progress bar and, if the new value
+ * is different to the old value, sends a {@link PropertyChangeEvent} (with
+ * the property name <code>"string"</code>) to all registered listeners. If
+ * the string is set to <code>null</code>, {@link #getString()} will return
+ * a default string.
*
- * @param string The string to be painted.
+ * @param string the string (<code>null</code> permitted).
+ *
+ * @see #getString()
+ * @see #setStringPainted(boolean)
*/
public void setString(String string)
{
@@ -412,32 +508,35 @@ public class JProgressBar extends JComponent implements SwingConstants,
string != progressString) || (string != null &&
! string.equals(progressString)))
{
- String oldString = progressString;
- progressString = string;
- firePropertyChange("string", oldString, progressString);
+ String oldString = progressString;
+ progressString = string;
+ firePropertyChange("string", oldString, progressString);
}
}
/**
- * This method returns the percent of the bar
- * that is "complete". (This is the amount value / (max - min)).
+ * Returns the current value expressed as a percentage. This is calculated
+ * as <code>(value - min) / (max - min)</code>.
*
- * @return DOCUMENT ME!
+ * @return The percentage (a value in the range 0.0 to 1.0).
*/
public double getPercentComplete()
{
if (getMaximum() == getMinimum())
return 1.0;
else
- return (double) (model.getValue() - model.getMinimum()) / (model
- .getMaximum()
- - model.getMinimum());
+ return (double) (model.getValue() - model.getMinimum())
+ / (model.getMaximum() - model.getMinimum());
}
/**
- * This method returns whether the border is painted.
+ * Returns a flag that controls whether or not the component's border is
+ * painted. The default value is <code>true</code>.
*
- * @return Whether the border is painted.
+ * @return <code>true</code> if the component's border should be painted,
+ * and <code>false</code> otherwise.
+ *
+ * @see #setBorderPainted(boolean)
*/
public boolean isBorderPainted()
{
@@ -445,25 +544,30 @@ public class JProgressBar extends JComponent implements SwingConstants,
}
/**
- * This method changes the borderPainted property.
+ * Sets the flag that controls whether or not the component's border is
+ * painted. If the flag value is changed, this method sends a
+ * {@link PropertyChangeEvent} (with the property name "borderPainted") to
+ * all registered listeners.
*
- * @param painted Whether the border is painted.
+ * @param painted the new flag value.
+ *
+ * @see #isBorderPainted()
+ * @see #paintBorder
*/
public void setBorderPainted(boolean painted)
{
if (painted != paintBorder)
{
- boolean oldPainted = paintBorder;
- paintBorder = painted;
- firePropertyChange("borderPainted", oldPainted,
- paintBorder);
+ boolean oldPainted = paintBorder;
+ paintBorder = painted;
+ firePropertyChange("borderPainted", oldPainted, paintBorder);
}
}
/**
- * This method returns the JProgressBar's UI delegate.
+ * Returns the UI delegate for this <code>JProgressBar</code>.
*
- * @return This JProgressBar's UI delegate.
+ * @return The UI delegate.
*/
public ProgressBarUI getUI()
{
@@ -471,9 +575,9 @@ public class JProgressBar extends JComponent implements SwingConstants,
}
/**
- * This method changes the UI property for this JProgressBar.
+ * Sets the UI delegate for this component.
*
- * @param ui The new UI delegate.
+ * @param ui the new UI delegate.
*/
public void setUI(ProgressBarUI ui)
{
@@ -481,8 +585,8 @@ public class JProgressBar extends JComponent implements SwingConstants,
}
/**
- * This method reverts the UI delegate for this JProgressBar
- * to the default for this Look and Feel.
+ * Sets this <code>JProgressBar</code>'s UI delegate to the default
+ * (obtained from the {@link UIManager}) for the current look and feel.
*/
public void updateUI()
{
@@ -490,11 +594,11 @@ public class JProgressBar extends JComponent implements SwingConstants,
}
/**
- * This method returns the identifier to allow the UIManager
- * to pick the correct class to act as the UI for
- * this JProgressBar.
+ * Returns the suffix (<code>"ProgressBarUI"</code> in this case) used to
+ * determine the class name for a UI delegate that can provide the look and
+ * feel for a <code>JProgressBar</code>.
*
- * @return The UIClassID: "ProgressBarUI".
+ * @return <code>"ProgressBarUI"</code>.
*/
public String getUIClassID()
{
@@ -502,27 +606,33 @@ public class JProgressBar extends JComponent implements SwingConstants,
}
/**
- * This method returns a ChangeListener that gets registered
- * model. By default, the ChangeListener, propagates the
- * ChangeEvents to the ChangeListeners of the JProgressBar.
+ * Creates a new {@link ChangeListener} that calls
+ * {@link #fireStateChanged()} whenever it receives a {@link ChangeEvent}
+ * (typically from the component's <code>model</code>). This listener is
+ * registered with the progress bar's model, so that changes made to the
+ * model directly will automatically result in the progress bar's listeners
+ * being notified also.
*
- * @return A new ChangeListener.
+ * @return A new listener.
*/
protected ChangeListener createChangeListener()
{
return new ChangeListener()
{
- public void stateChanged(ChangeEvent ce)
- {
- fireStateChanged();
- }
+ public void stateChanged(ChangeEvent ce)
+ {
+ fireStateChanged();
+ }
};
}
/**
- * This method adds a ChangeListener to this JProgressBar.
+ * Registers a listener with this component so that it will receive
+ * notification of component state changes.
*
- * @param listener The ChangeListener to add to this JProgressBar.
+ * @param listener the listener.
+ *
+ * @see #removeChangeListener(ChangeListener)
*/
public void addChangeListener(ChangeListener listener)
{
@@ -530,9 +640,12 @@ public class JProgressBar extends JComponent implements SwingConstants,
}
/**
- * This method removes a ChangeListener from this JProgressBar.
+ * Deregisters a listener so that it no longer receives notification of
+ * component state changes.
*
- * @param listener The ChangeListener to remove from this JProgressBar.
+ * @param listener the listener.
+ *
+ * @see #addChangeListener(ChangeListener)
*/
public void removeChangeListener(ChangeListener listener)
{
@@ -540,10 +653,12 @@ public class JProgressBar extends JComponent implements SwingConstants,
}
/**
- * This method returns an array of all ChangeListeners listening to this
- * progress bar.
+ * Returns an array of the listeners that are registered with this component.
+ * The array may be empty, but is never <code>null</code>.
*
- * @return An array of ChangeListeners listening to this progress bar.
+ * @return An array of listeners.
+ *
+ * @since 1.4
*/
public ChangeListener[] getChangeListeners()
{
@@ -551,9 +666,10 @@ public class JProgressBar extends JComponent implements SwingConstants,
}
/**
- * This method is called when the JProgressBar receives a ChangeEvent
- * from its model. This simply propagates the event (changing the source
- * to the JProgressBar) to the JProgressBar's listeners.
+ * Sends a {@link ChangeEvent} to all registered listeners to indicate that
+ * the state of the <code>JProgressBar</code> has changed.
+ *
+ * @see #createChangeListener()
*/
protected void fireStateChanged()
{
@@ -562,15 +678,17 @@ public class JProgressBar extends JComponent implements SwingConstants,
changeEvent = new ChangeEvent(this);
for (int i = changeListeners.length - 2; i >= 0; i -= 2)
{
- if (changeListeners[i] == ChangeListener.class)
- ((ChangeListener) changeListeners[i + 1]).stateChanged(changeEvent);
+ if (changeListeners[i] == ChangeListener.class)
+ ((ChangeListener) changeListeners[i + 1]).stateChanged(changeEvent);
}
}
/**
- * This method returns the model used with this JProgressBar.
+ * Returns the model for the <code>JProgressBar</code>.
*
- * @return The model used with this JProgressBar.
+ * @return The model (never <code>null</code>).
+ *
+ * @see #setModel(BoundedRangeModel)
*/
public BoundedRangeModel getModel()
{
@@ -578,25 +696,32 @@ public class JProgressBar extends JComponent implements SwingConstants,
}
/**
- * This method changes the model property for this JProgressBar.
+ * Sets the model for the <code>JProgressBar</code> and sends a
+ * {@link ChangeEvent} to all registered listeners.
*
- * @param model The model to use with this JProgressBar.
+ * @param model the model (<code>null</code> not permitted).
+ *
+ * @see #getModel()
*/
public void setModel(BoundedRangeModel model)
{
if (model != this.model)
{
this.model.removeChangeListener(changeListener);
- this.model = model;
- this.model.addChangeListener(changeListener);
- fireStateChanged();
+ this.model = model;
+ this.model.addChangeListener(changeListener);
+ fireStateChanged();
}
}
/**
- * This method returns the minimum value of this JProgressBar.
+ * Returns the minimum value for the <code>JProgressBar</code>. This defines
+ * the lower bound for the current value, and is stored in the component's
+ * <code>model</code>.
*
- * @return The minimum value of this JProgressBar.
+ * @return The minimum value.
+ *
+ * @see #setMinimum(int)
*/
public int getMinimum()
{
@@ -604,9 +729,16 @@ public class JProgressBar extends JComponent implements SwingConstants,
}
/**
- * This method sets the minimum value of this JProgressBar.
- *
- * @param minimum The minimum value of this JProgressBar.
+ * Sets the minimum value for the <code>JProgressBar</code>. The value is
+ * stored in the component's <code>model</code> (see {@link #getModel()}).
+ * If the new value is different to the old value, a {@link ChangeEvent} is
+ * sent to the model's registered listeners. In turn, this triggers a call
+ * to {@link #fireStateChanged()} which will send a <code>ChangeEvent</code>
+ * to this component's registered listeners.
+ *
+ * @param minimum the minimum value.
+ *
+ * @see #getMinimum()
*/
public void setMinimum(int minimum)
{
@@ -614,9 +746,13 @@ public class JProgressBar extends JComponent implements SwingConstants,
}
/**
- * This method returns the maximum value of this JProgressBar.
+ * Returns the maximum value for the <code>JProgressBar</code>. This defines
+ * the upper bound for the current value, and is stored in the component's
+ * <code>model</code>.
*
- * @return The maximum value of this JProgressBar.
+ * @return The maximum value.
+ *
+ * @see #setMaximum(int)
*/
public int getMaximum()
{
@@ -624,9 +760,16 @@ public class JProgressBar extends JComponent implements SwingConstants,
}
/**
- * This method sets the maximum value of this JProgressBar.
+ * Sets the maximum value for the <code>JProgressBar</code>. The value is
+ * stored in the component's <code>model</code> (see {@link #getModel()}).
+ * If the new value is different to the old value, a {@link ChangeEvent} is
+ * sent to the model's registered listeners. In turn, this triggers a call
+ * to {@link #fireStateChanged()} which will send a <code>ChangeEvent</code>
+ * to this component's registered listeners.
*
- * @param maximum The maximum value of this JProgressBar.
+ * @param maximum the maximum value.
+ *
+ * @see #getMaximum()
*/
public void setMaximum(int maximum)
{
@@ -659,29 +802,40 @@ public class JProgressBar extends JComponent implements SwingConstants,
}
/**
- * This method changes the indeterminate property. If the
- * JProgressBar is determinate, it paints a percentage
- * of the bar described by its value. If it is indeterminate,
- * it simply bounces a box between the ends of the bar; the
- * value of the JProgressBar is ignored.
+ * Sets the flag that controls the mode for this <code>JProgressBar</code>
+ * (<code>true</code> for indeterminate mode, and <code>false</code> for
+ * determinate mode). If the flag value changes, this method sends a
+ * {@link PropertyChangeEvent} (with the property name
+ * <code>"indeterminate"</code>) to all registered listeners.
+ * <p>
+ * If the <code>JProgressBar</code> is determinate, it paints a percentage
+ * of the bar described by its value. If it is indeterminate, it simply
+ * bounces a box between the ends of the bar; the value of the
+ * <code>JProgressBar</code> is ignored.
*
- * @param newValue Whether the JProgressBar is indeterminate.
+ * @param flag the new flag value.
+ *
+ * @see #isIndeterminate()
+ * @since 1.4
*/
- public void setIndeterminate(boolean newValue)
+ public void setIndeterminate(boolean flag)
{
- if (indeterminate != newValue)
+ if (indeterminate != flag)
{
- boolean olddeter = indeterminate;
- indeterminate = newValue;
- firePropertyChange("indeterminate", olddeter,
- indeterminate);
+ indeterminate = flag;
+ firePropertyChange("indeterminate", !flag, indeterminate);
}
}
/**
- * This method returns whether the JProgressBar is indeterminate.
+ * Returns a flag that indicates the mode for this <code>JProgressBar</code>
+ * (<code>true</code> for indeterminate mode, and <code>false</code> for
+ * determinate mode).
*
- * @return Whether this JProgressBar is indeterminate.
+ * @return A flag indicating the mode for the <code>JProgressBar</code>.
+ *
+ * @see #setIndeterminate(boolean)
+ * @since 1.4
*/
public boolean isIndeterminate()
{
diff --git a/javax/swing/JRootPane.java b/javax/swing/JRootPane.java
index 5c4723596..a2cd9c7a0 100644
--- a/javax/swing/JRootPane.java
+++ b/javax/swing/JRootPane.java
@@ -551,7 +551,6 @@ public class JRootPane extends JComponent implements Accessible
JPanel p = new JPanel();
p.setName(this.getName() + ".contentPane");
p.setLayout(new BorderLayout());
- p.setBackground(null);
return p;
}
diff --git a/javax/swing/JScrollPane.java b/javax/swing/JScrollPane.java
index 09e37378b..45df1d919 100644
--- a/javax/swing/JScrollPane.java
+++ b/javax/swing/JScrollPane.java
@@ -170,7 +170,8 @@ public class JScrollPane extends JComponent
return columnHeader;
}
- public Component getCorner(String key) {
+ public Component getCorner(String key)
+ {
if (getComponentOrientation()
== ComponentOrientation.LEFT_TO_RIGHT)
{
@@ -247,7 +248,7 @@ public class JScrollPane extends JComponent
if (viewportBorder == null)
{
if (getViewport() == null)
- return new Rectangle(0,0,0,0);
+ return new Rectangle(0, 0, 0, 0);
else
return getViewport().getBounds();
}
@@ -255,8 +256,7 @@ public class JScrollPane extends JComponent
{
Insets i = viewportBorder.getBorderInsets(getViewport());
if (getViewport() == null)
- return new Rectangle(0,0,
- i.left+i.right, i.top+i.bottom);
+ return new Rectangle(0, 0, i.left + i.right, i.top + i.bottom);
else
{
Rectangle b = getViewport().getBounds();
diff --git a/javax/swing/JSlider.java b/javax/swing/JSlider.java
index ed94c4ecc..8a06d4f01 100644
--- a/javax/swing/JSlider.java
+++ b/javax/swing/JSlider.java
@@ -227,13 +227,13 @@ public class JSlider extends JComponent implements SwingConstants, Accessible,
}
/** Whether or not this slider paints its ticks. */
- private transient boolean paintTicks = false;
+ private transient boolean paintTicks;
/** Whether or not this slider paints its track. */
private transient boolean paintTrack = true;
/** Whether or not this slider paints its labels. */
- private transient boolean paintLabels = false;
+ private transient boolean paintLabels;
/**
* A dictionary of (Integer, Component) pairs where each Component is a
@@ -251,7 +251,7 @@ public class JSlider extends JComponent implements SwingConstants, Accessible,
protected int minorTickSpacing;
/** Whether the slider snaps its values to ticks. */
- protected boolean snapToTicks = false;
+ protected boolean snapToTicks;
/** The orientation (horizontal or vertical) of the slider. */
protected int orientation = HORIZONTAL;
diff --git a/javax/swing/JSpinner.java b/javax/swing/JSpinner.java
index 70045ed53..16a210600 100644
--- a/javax/swing/JSpinner.java
+++ b/javax/swing/JSpinner.java
@@ -106,7 +106,7 @@ public class JSpinner extends JComponent
add(ftf);
ftf.setValue(spinner.getValue());
ftf.addPropertyChangeListener(this);
- if(getComponentOrientation().isLeftToRight())
+ if (getComponentOrientation().isLeftToRight())
ftf.setHorizontalAlignment(JTextField.RIGHT);
else
ftf.setHorizontalAlignment(JTextField.LEFT);
diff --git a/javax/swing/JTabbedPane.java b/javax/swing/JTabbedPane.java
index 34ab8eeaa..7e2864b8a 100644
--- a/javax/swing/JTabbedPane.java
+++ b/javax/swing/JTabbedPane.java
@@ -1,5 +1,5 @@
/* JTabbedPane.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,8 +38,6 @@ exception statement from your version. */
package javax.swing;
-import gnu.classpath.NotImplementedException;
-
import java.awt.Color;
import java.awt.Component;
import java.awt.Point;
@@ -53,6 +51,7 @@ import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.accessibility.AccessibleSelection;
+import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
@@ -79,8 +78,6 @@ public class JTabbedPane extends JComponent implements Serializable,
/**
* Accessibility support for <code>JTabbedPane</code>.
*/
- // FIXME: This inner class is a complete stub and must be implemented
- // properly.
protected class AccessibleJTabbedPane extends JComponent.AccessibleJComponent
implements AccessibleSelection, ChangeListener
{
@@ -99,14 +96,17 @@ public class JTabbedPane extends JComponent implements Serializable,
/**
* Receives notification when the selection state of the
- * <code>JTabbedPane</code> changes.
+ * <code>JTabbedPane</code> changes and fires appropriate property change
+ * events to interested listeners.
*
* @param e the change event describing the change
*/
public void stateChanged(ChangeEvent e)
- throws NotImplementedException
{
- // Implement this properly.
+ // I couldn't figure out what else should be done here.
+ Object source = e.getSource();
+ firePropertyChange(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY,
+ null, source);
}
/**
@@ -116,9 +116,8 @@ public class JTabbedPane extends JComponent implements Serializable,
* @return the accessible role of the <code>JTabbedPane</code>
*/
public AccessibleRole getAccessibleRole()
- throws NotImplementedException
{
- return null;
+ return AccessibleRole.PAGE_TAB_LIST;
}
/**
@@ -129,9 +128,8 @@ public class JTabbedPane extends JComponent implements Serializable,
* <code>JTabbedPane</code>
*/
public int getAccessibleChildrenCount()
- throws NotImplementedException
{
- return 0;
+ return getTabCount();
}
/**
@@ -158,9 +156,8 @@ public class JTabbedPane extends JComponent implements Serializable,
* @return the current selection state of the <code>JTabbedPane</code>
*/
public AccessibleSelection getAccessibleSelection()
- throws NotImplementedException
{
- return null;
+ return this;
}
/**
@@ -175,90 +172,99 @@ public class JTabbedPane extends JComponent implements Serializable,
* this location
*/
public Accessible getAccessibleAt(Point p)
- throws NotImplementedException
{
- return null;
+ int tabIndex = indexAtLocation(p.x, p.y);
+ if (tabIndex >= 0)
+ return getAccessibleChild(tabIndex);
+ else
+ return getAccessibleSelection(0);
}
/**
- * The number of selected child components of the
- * <code>JTabbedPane</code>. This will be <code>0</code> if the
- * <code>JTabbedPane</code> has no children, or <code>1</code> otherwise,
- * since there is always exactly one tab selected.
+ * Returns the number of selected child components of the
+ * <code>JTabbedPane</code>. The reference implementation appears
+ * to return <code>1</code> always and we do the same.
*
- * @return number of selected child components of the
- * <code>JTabbedPane</code>
+ * @return <code>1</code>
*/
public int getAccessibleSelectionCount()
- throws NotImplementedException
{
- return 0;
+ return 1;
}
/**
- * DOCUMENT ME!
+ * Returns the selected tab, or <code>null</code> if there is no
+ * selection.
*
- * @param i DOCUMENT ME!
+ * @param i the selection index (ignored here).
*
- * @return DOCUMENT ME!
+ * @return The selected tab, or <code>null</code>.
*/
public Accessible getAccessibleSelection(int i)
- throws NotImplementedException
{
- return null;
+ Accessible result = null;
+ int selected = getSelectedIndex();
+ if (selected >= 0)
+ result = (Page) tabs.get(selected);
+ return result;
}
/**
- * DOCUMENT ME!
+ * Returns <code>true</code> if the specified child is selected,
+ * and <code>false</code> otherwise.
*
- * @param i DOCUMENT ME!
+ * @param i the child index.
*
- * @return DOCUMENT ME!
+ * @return A boolean.
*/
public boolean isAccessibleChildSelected(int i)
- throws NotImplementedException
{
- return false;
+ return i == getSelectedIndex();
}
/**
- * DOCUMENT ME!
+ * Selects the specified tab.
*
- * @param i DOCUMENT ME!
+ * @param i the index of the item to select.
*/
public void addAccessibleSelection(int i)
- throws NotImplementedException
{
- // TODO: Implement this properly.
+ setSelectedIndex(i);
}
/**
- * DOCUMENT ME!
+ * Does nothing - it makes no sense to remove a selection for a
+ * tabbed pane, since one tab must always be selected.
*
- * @param i DOCUMENT ME!
+ * @param i the item index.
+ *
+ * @see #addAccessibleSelection(int)
*/
public void removeAccessibleSelection(int i)
- throws NotImplementedException
{
- // TODO: Implement this properly.
+ // do nothing
}
/**
- * DOCUMENT ME!
+ * Does nothing - it makes no sense to clear the selection for
+ * a tabbed pane, since one tab must always be selected.
+ *
+ * @see #addAccessibleSelection(int)
*/
public void clearAccessibleSelection()
- throws NotImplementedException
{
- // TODO: Implement this properly.
+ // do nothing
}
/**
- * DOCUMENT ME!
+ * Does nothing - it makes no sense to select all for a tabbed
+ * pane, since only one tab can be selected at a time.
+ *
+ * @see #addAccessibleSelection(int)
*/
public void selectAllAccessibleSelection()
- throws NotImplementedException
{
- // TODO: Implement this properly.
+ // do nothing
}
}
@@ -267,7 +273,6 @@ public class JTabbedPane extends JComponent implements Serializable,
*/
protected class ModelListener implements ChangeListener, Serializable
{
- /** DOCUMENT ME! */
private static final long serialVersionUID = 497359819958114132L;
/**
@@ -446,7 +451,6 @@ public class JTabbedPane extends JComponent implements Serializable,
return title;
}
- /** DOCUMENT ME! */
private static final long serialVersionUID = 1614381073220130939L;
/**
@@ -598,6 +602,19 @@ public class JTabbedPane extends JComponent implements Serializable,
}
/**
+ * Returns the accessible name for this tab.
+ *
+ * @return The accessible name.
+ */
+ public String getAccessibleName()
+ {
+ if (accessibleName != null)
+ return accessibleName;
+ else
+ return title;
+ }
+
+ /**
* Returns the accessible role of this tab, which is always
* {@link AccessibleRole#PAGE_TAB}.
*
@@ -608,18 +625,31 @@ public class JTabbedPane extends JComponent implements Serializable,
return AccessibleRole.PAGE_TAB;
}
+ /**
+ * Returns the accessible state set of this object.
+ *
+ * @return the accessible state set of this object
+ */
public AccessibleStateSet getAccessibleStateSet()
- throws NotImplementedException
{
- // FIXME: Implement this properly.
- return null;
+ AccessibleContext parentCtx = JTabbedPane.this.getAccessibleContext();
+ AccessibleStateSet state = parentCtx.getAccessibleStateSet();
+ state.add(AccessibleState.SELECTABLE);
+ if (component == getSelectedComponent())
+ state.add(AccessibleState.SELECTED);
+ return state;
}
+ /**
+ * Returns the index of this tab inside its parent.
+ *
+ * @return the index of this tab inside its parent
+ */
public int getAccessibleIndexInParent()
- throws NotImplementedException
{
- // FIXME: Implement this properly.
- return 0;
+ // TODO: Not sure if the title is unambiguous, but I can't figure
+ // another way of doing this.
+ return indexOfTab(title);
}
/**
@@ -1623,25 +1653,45 @@ public class JTabbedPane extends JComponent implements Serializable,
}
/**
- * This method returns a string representation of this JTabbedPane. It is
- * mainly used for debugging purposes.
+ * Returns a string describing the attributes for the
+ * <code>JTabbedPane</code> component, for use in debugging. The return
+ * value is guaranteed to be non-<code>null</code>, but the format of the
+ * string may vary between implementations.
*
- * @return A string representation of this JTabbedPane.
+ * @return A string describing the attributes of the
+ * <code>JTabbedPane</code>.
*/
protected String paramString()
{
- return "JTabbedPane";
+ StringBuffer sb = new StringBuffer(super.paramString());
+ sb.append(",tabPlacement=");
+ if (tabPlacement == TOP)
+ sb.append("TOP");
+ if (tabPlacement == BOTTOM)
+ sb.append("BOTTOM");
+ if (tabPlacement == LEFT)
+ sb.append("LEFT");
+ if (tabPlacement == RIGHT)
+ sb.append("RIGHT");
+ return sb.toString();
}
/**
- * DOCUMENT ME!
+ * Returns the object that provides accessibility features for this
+ * <code>JTabbedPane</code> component.
*
- * @return DOCUMENT ME!
+ * @return The accessible context (an instance of
+ * {@link AccessibleJTabbedPane}).
*/
public AccessibleContext getAccessibleContext()
{
if (accessibleContext == null)
- accessibleContext = new AccessibleJTabbedPane();
+ {
+ AccessibleJTabbedPane ctx = new AccessibleJTabbedPane();
+ addChangeListener(ctx);
+ accessibleContext = ctx;
+ }
+
return accessibleContext;
}
}
diff --git a/javax/swing/JTable.java b/javax/swing/JTable.java
index 348534469..4f93da8d2 100644
--- a/javax/swing/JTable.java
+++ b/javax/swing/JTable.java
@@ -63,6 +63,7 @@ import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleExtendedTable;
import javax.accessibility.AccessibleRole;
import javax.accessibility.AccessibleSelection;
+import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
import javax.accessibility.AccessibleTable;
import javax.accessibility.AccessibleTableModelChange;
@@ -165,6 +166,8 @@ public class JTable
public AccessibleRole getAccessibleRole()
{
// TODO: What is the role of the table cell?
+ // Seems like the RI returns UNKNOWN here for 'normal' cells, might
+ // be different for special renderers though (not tested yet).
return AccessibleRole.UNKNOWN;
}
@@ -175,8 +178,27 @@ public class JTable
*/
public AccessibleStateSet getAccessibleStateSet()
{
- // TODO: What state shoiuld be returned here?
- return new AccessibleStateSet();
+ AccessibleStateSet state = new AccessibleStateSet();
+
+ // Figure out the SHOWING state.
+ Rectangle visibleRect = getVisibleRect();
+ Rectangle cellRect = getCellRect(row, column, false);
+ if (visibleRect.intersects(cellRect))
+ state.add(AccessibleState.SHOWING);
+
+ // Figure out SELECTED state.
+ if (isCellSelected(row, column))
+ state.add(AccessibleState.SELECTED);
+
+ // Figure out ACTIVE state.
+ if (row == getSelectedRow() && column == getSelectedColumn())
+ state.add(AccessibleState.ACTIVE);
+
+ // TRANSIENT seems to be always set in the RI.
+ state.add(AccessibleState.TRANSIENT);
+
+ // TODO: Any other state to handle here?
+ return state;
}
/**
@@ -594,7 +616,463 @@ public class JTable
return lastColumn;
}
}
-
+
+ /**
+ * The RI returns an instance with this name in
+ * {@link #getAccessibleColumnHeader()}, this makes sense, so we do the
+ * same.
+ */
+ private class AccessibleTableHeader
+ implements AccessibleTable
+ {
+
+ /**
+ * The JTableHeader wrapped by this class.
+ */
+ private JTableHeader header;
+
+ /**
+ * Creates a new instance.
+ *
+ * @param h the JTableHeader to wrap
+ */
+ private AccessibleTableHeader(JTableHeader h)
+ {
+ header = h;
+ }
+
+ /**
+ * Returns the caption for the table header.
+ *
+ * @return the caption for the table header
+ */
+ public Accessible getAccessibleCaption()
+ {
+ // The RI seems to always return null here, so do we.
+ return null;
+ }
+
+ /**
+ * Sets the caption for the table header.
+ *
+ * @param caption the caption to set
+ */
+ public void setAccessibleCaption(Accessible caption)
+ {
+ // This seems to be a no-op in the RI, so we do the same.
+ }
+
+ /**
+ * Returns the caption for the table header.
+ *
+ * @return the caption for the table header
+ */
+ public Accessible getAccessibleSummary()
+ {
+ // The RI seems to always return null here, so do we.
+ return null;
+ }
+
+ /**
+ * Sets the summary for the table header.
+ *
+ * @param summary the caption to set
+ */
+ public void setAccessibleSummary(Accessible summary)
+ {
+ // This seems to be a no-op in the RI, so we do the same.
+ }
+
+ /**
+ * Returns the number of rows, which is always 1 for the table header.
+ *
+ * @return the number of rows
+ */
+ public int getAccessibleRowCount()
+ {
+ return 1;
+ }
+
+ /**
+ * Returns the number of columns in the table header.
+ *
+ * @return the number of columns in the table header
+ */
+ public int getAccessibleColumnCount()
+ {
+ return header.getColumnModel().getColumnCount();
+ }
+
+ /**
+ * Returns the accessible child at the specified row and column.
+ * The row number is ignored here, and we return an
+ * AccessibleJTableHeaderCell here with the renderer component as
+ * component.
+ *
+ * @param r the row number
+ * @param c the column number
+ *
+ * @return the accessible child at the specified row and column
+ */
+ public Accessible getAccessibleAt(int r, int c)
+ {
+ TableColumn column = header.getColumnModel().getColumn(c);
+ TableCellRenderer rend = column.getHeaderRenderer();
+ if (rend == null)
+ rend = header.getDefaultRenderer();
+ Component comp =
+ rend.getTableCellRendererComponent(header.getTable(),
+ column.getHeaderValue(), false,
+ false, -1, c);
+ return new AccessibleJTableHeaderCell(header, comp, r, c);
+ }
+
+ public int getAccessibleRowExtentAt(int r, int c)
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public int getAccessibleColumnExtentAt(int r, int c)
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public AccessibleTable getAccessibleRowHeader()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void setAccessibleRowHeader(AccessibleTable header)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public AccessibleTable getAccessibleColumnHeader()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void setAccessibleColumnHeader(AccessibleTable header)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public Accessible getAccessibleRowDescription(int r)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void setAccessibleRowDescription(int r, Accessible description)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public Accessible getAccessibleColumnDescription(int c)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void setAccessibleColumnDescription(int c, Accessible description)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public boolean isAccessibleSelected(int r, int c)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public boolean isAccessibleRowSelected(int r)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public boolean isAccessibleColumnSelected(int c)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public int[] getSelectedAccessibleRows()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public int[] getSelectedAccessibleColumns()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ }
+
+ /**
+ * The RI returns an instance of such class for table header cells. This
+ * makes sense so I added this class. This still needs to be fully
+ * implemented, I just don't feel motivated enough to do so just now.
+ */
+ private class AccessibleJTableHeaderCell
+ extends AccessibleContext
+ implements Accessible, AccessibleComponent
+ {
+
+ private AccessibleJTableHeaderCell(JTableHeader h, Component comp, int r,
+ int c)
+ {
+
+ }
+
+ public AccessibleRole getAccessibleRole()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public AccessibleStateSet getAccessibleStateSet()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public int getAccessibleIndexInParent()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public int getAccessibleChildrenCount()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public Accessible getAccessibleChild(int i)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Locale getLocale()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public AccessibleContext getAccessibleContext()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Color getBackground()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void setBackground(Color color)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public Color getForeground()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void setForeground(Color color)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public Cursor getCursor()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void setCursor(Cursor cursor)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public Font getFont()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void setFont(Font font)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public FontMetrics getFontMetrics(Font font)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public boolean isEnabled()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public void setEnabled(boolean b)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public boolean isVisible()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public void setVisible(boolean b)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public boolean isShowing()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public boolean contains(Point point)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public Point getLocationOnScreen()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Point getLocation()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void setLocation(Point point)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public Rectangle getBounds()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void setBounds(Rectangle rectangle)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public Dimension getSize()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void setSize(Dimension dimension)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public Accessible getAccessibleAt(Point point)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public boolean isFocusTraversable()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public void requestFocus()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void addFocusListener(FocusListener listener)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void removeFocusListener(FocusListener listener)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ }
+
+ /**
+ * The last selected row. This is needed to track the selection in
+ * {@link #valueChanged(ListSelectionEvent)}.
+ */
+ private int lastSelectedRow;
+
+ /**
+ * The last selected column. This is needed to track the selection in
+ * {@link #valueChanged(ListSelectionEvent)}.
+ */
+ private int lastSelectedColumn;
+
+ /**
+ * The caption of the table.
+ */
+ private Accessible caption;
+
+ /**
+ * The summary of the table.
+ */
+ private Accessible summary;
+
+ /**
+ * Accessible descriptions for rows.
+ */
+ private Accessible[] rowDescriptions;
+
+ /**
+ * Accessible descriptions for columns.
+ */
+ private Accessible[] columnDescriptions;
+
/**
* Creates a new <code>AccessibleJTable</code>.
*
@@ -605,10 +1083,34 @@ public class JTable
getModel().addTableModelListener(this);
getSelectionModel().addListSelectionListener(this);
getColumnModel().addColumnModelListener(this);
- getCellEditor().addCellEditorListener(this);
+ lastSelectedRow = getSelectedRow();
+ lastSelectedColumn = getSelectedColumn();
+ TableCellEditor editor = getCellEditor();
+ if (editor != null)
+ editor.addCellEditorListener(this);
}
/**
+ * Returns the accessible role for the <code>JTable</code> component.
+ *
+ * @return {@link AccessibleRole#TABLE}.
+ */
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.TABLE;
+ }
+
+ /**
+ * Returns the accessible table.
+ *
+ * @return <code>this</code>.
+ */
+ public AccessibleTable getAccessibleTable()
+ {
+ return this;
+ }
+
+ /**
* Returns the number of selected items in this table.
*/
public int getAccessibleSelectionCount()
@@ -616,46 +1118,197 @@ public class JTable
return getSelectedColumnCount();
}
+ /**
+ * Returns the selected accessible object with the specified index
+ * <code>i</code>. This basically returns the i-th selected cell in the
+ * table when going though it row-wise, and inside the rows, column-wise.
+ *
+ * @param i the index of the selected object to find
+ *
+ * @return the selected accessible object with the specified index
+ * <code>i</code>
+ */
public Accessible getAccessibleSelection(int i)
{
- // TODO Auto-generated method stub
- return null;
+ Accessible found = null;
+
+ int[] selectedRows = getSelectedRows();
+ int[] selectedColumns = getSelectedColumns();
+ int numCols = getColumnCount();
+ int numRows = getRowCount();
+
+ // We have to go through every selected row and column and count until we
+ // find the specified index. This is potentially inefficient, but I can't
+ // think of anything better atm.
+ if (getRowSelectionAllowed() && getColumnSelectionAllowed())
+ {
+ int current = -1;
+ int newIndex = current;
+ int lastSelectedRow = -1;
+ // Go through the selected rows array, don't forget the selected
+ // cells inside the not-selected rows' columns.
+ for (int j = 0; i < selectedRows.length; i++)
+ {
+ // Handle unselected rows between this selected and the last
+ // selected row, if any.
+ int selectedRow = selectedRows[j];
+ int r = -1;
+ int ci = -1;
+ for (r = lastSelectedRow + 1;
+ r < selectedRow && current < i; r++)
+ {
+ for (ci = 0; ci < selectedColumns.length && current < i;
+ ci++)
+ {
+ current++;
+ }
+ }
+ if (current == i)
+ {
+ // We found the cell in the above loops, now get out of here.
+ found = getAccessibleChild(r * numCols
+ + selectedColumns[ci]);
+ break;
+ }
+
+ // If we're still here, handle the current selected row.
+ if (current < i && current + numCols >= i)
+ {
+ // The cell must be in that row, which one is it?
+ found = getAccessibleChild(r * numCols + (i - current));
+ break;
+ }
+ current += numCols;
+ }
+ if (found == null)
+ {
+ // The cell can still be in the last couple of unselected rows.
+ int r = 0;
+ int ci = 0;
+ for (r = lastSelectedRow + 1;
+ r < numRows && current < i; r++)
+ {
+ for (ci = 0; ci < selectedColumns.length && current < i;
+ ci++)
+ {
+ current++;
+ }
+ }
+ if (current == i)
+ {
+ // We found the cell in the above loops, now get out of here.
+ found = getAccessibleChild(r * numCols
+ + selectedColumns[ci]);
+ }
+ }
+ }
+ // One or more rows can be completely selected.
+ else if (getRowSelectionAllowed())
+ {
+ int c = i % numCols;
+ int r = selectedRows[i / numCols];
+ found = getAccessibleChild(r * numCols + c);
+ }
+ // One or more columns can be completely selected.
+ else if (getRowSelectionAllowed())
+ {
+ int numSelectedColumns = selectedColumns.length;
+ int c = selectedColumns[i % numSelectedColumns];
+ int r = i / numSelectedColumns;
+ found = getAccessibleChild(r * numCols + c);
+ }
+
+ return found;
}
+ /**
+ * Returns <code>true</code> if the accessible child with the index
+ * <code>i</code> is selected, <code>false</code> otherwise.
+ *
+ * @param i the index of the accessible to check
+ *
+ * @return <code>true</code> if the accessible child with the index
+ * <code>i</code> is selected, <code>false</code> otherwise
+ */
public boolean isAccessibleChildSelected(int i)
{
- // TODO Auto-generated method stub
- return false;
+ int r = getAccessibleRowAtIndex(i);
+ int c = getAccessibleColumnAtIndex(i);
+ return isCellSelected(r, c);
}
+ /**
+ * Adds the accessible child with the specified index <code>i</code> to the
+ * selection.
+ *
+ * @param i the index of the accessible child to add to the selection
+ */
public void addAccessibleSelection(int i)
{
- // TODO Auto-generated method stub
-
+ int r = getAccessibleRowAtIndex(i);
+ int c = getAccessibleColumnAtIndex(i);
+ changeSelection(r, c, true, false);
}
+ /**
+ * Removes the accessible child with the specified index <code>i</code>
+ * from the current selection. This will only work on tables that have
+ * cell selection enabled (<code>rowSelectionAllowed == false &&
+ * columnSelectionAllowed == false</code>).
+ *
+ * @param i the index of the accessible to be removed from the selection
+ */
public void removeAccessibleSelection(int i)
{
- // TODO Auto-generated method stub
-
+ if (! getRowSelectionAllowed() && ! getColumnSelectionAllowed())
+ {
+ int r = getAccessibleRowAtIndex(i);
+ int c = getAccessibleColumnAtIndex(i);
+ removeRowSelectionInterval(r, r);
+ removeColumnSelectionInterval(c, c);
+ }
}
+ /**
+ * Deselects all selected accessible children.
+ */
public void clearAccessibleSelection()
{
- // TODO Auto-generated method stub
-
+ clearSelection();
}
+ /**
+ * Selects all accessible children that can be selected. This will only
+ * work on tables that support multiple selections and that have individual
+ * cell selection enabled.
+ */
public void selectAllAccessibleSelection()
{
- // TODO Auto-generated method stub
-
+ selectAll();
}
+ /**
+ * Receives notification when the row selection changes and fires
+ * appropriate property change events.
+ *
+ * @param event the list selection event
+ */
public void valueChanged(ListSelectionEvent event)
{
- // TODO Auto-generated method stub
-
+ firePropertyChange(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY,
+ Boolean.FALSE, Boolean.TRUE);
+ int r = getSelectedRow();
+ int c = getSelectedColumn();
+ if (r != lastSelectedRow || c != lastSelectedColumn)
+ {
+ Accessible o = getAccessibleAt(lastSelectedRow,
+ lastSelectedColumn);
+ Accessible n = getAccessibleAt(r, c);
+ firePropertyChange(AccessibleContext
+ .ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY, o, n);
+ lastSelectedRow = r;
+ lastSelectedColumn = c;
+ }
}
/**
@@ -680,14 +1333,13 @@ public class JTable
/**
* Receives notification when one or more rows have been inserted into the
- * table.
+ * table and fires appropriate property change events.
*
* @param event the table model event
*/
public void tableRowsInserted(TableModelEvent event)
{
- // TODO: What to do here, if anything? This might be a hook method for
- // subclasses...
+ handleRowChange(event);
}
/**
@@ -698,50 +1350,93 @@ public class JTable
*/
public void tableRowsDeleted(TableModelEvent event)
{
- // TODO: What to do here, if anything? This might be a hook method for
- // subclasses...
+ handleRowChange(event);
+ }
+
+ /**
+ * Fires a PropertyChangeEvent for inserted or deleted rows.
+ *
+ * @param event the table model event
+ */
+ private void handleRowChange(TableModelEvent event)
+ {
+ firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
+ null, null);
+ int firstColumn = event.getColumn();
+ int lastColumn = event.getColumn();
+ if (firstColumn == TableModelEvent.ALL_COLUMNS)
+ {
+ firstColumn = 0;
+ lastColumn = getColumnCount() - 1;
+ }
+ AccessibleJTableModelChange change = new AccessibleJTableModelChange
+ (event.getType(), event.getFirstRow(), event.getLastRow(),
+ firstColumn, lastColumn);
+ firePropertyChange(AccessibleContext.ACCESSIBLE_TABLE_MODEL_CHANGED,
+ null, change);
}
public void columnAdded(TableColumnModelEvent event)
{
- // TODO Auto-generated method stub
-
+ firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
+ null, null);
+ handleColumnChange(AccessibleTableModelChange.INSERT,
+ event.getFromIndex(), event.getToIndex());
}
- public void columnMarginChanged(ChangeEvent event)
+ public void columnRemoved(TableColumnModelEvent event)
{
- // TODO Auto-generated method stub
-
+ firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
+ null, null);
+ handleColumnChange(AccessibleTableModelChange.DELETE,
+ event.getFromIndex(), event.getToIndex());
}
public void columnMoved(TableColumnModelEvent event)
{
- // TODO Auto-generated method stub
-
+ firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
+ null, null);
+ handleColumnChange(AccessibleTableModelChange.DELETE,
+ event.getFromIndex(), event.getFromIndex());
+ handleColumnChange(AccessibleTableModelChange.INSERT,
+ event.getFromIndex(), event.getToIndex());
}
- public void columnRemoved(TableColumnModelEvent event)
+ /**
+ * Fires a PropertyChangeEvent for inserted or deleted columns.
+ *
+ * @param type the type of change
+ * @param from the start of the change
+ * @param to the target of the change
+ */
+ private void handleColumnChange(int type, int from, int to)
{
- // TODO Auto-generated method stub
-
+ AccessibleJTableModelChange change =
+ new AccessibleJTableModelChange(type, 0, 0, from, to);
+ firePropertyChange(AccessibleContext.ACCESSIBLE_TABLE_MODEL_CHANGED,
+ null, change);
+ }
+
+ public void columnMarginChanged(ChangeEvent event)
+ {
+ firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
+ null, null);
}
public void columnSelectionChanged(ListSelectionEvent event)
{
- // TODO Auto-generated method stub
-
+ // AFAICS, nothing is done here.
}
public void editingCanceled(ChangeEvent event)
{
- // TODO Auto-generated method stub
-
+ // AFAICS, nothing is done here.
}
public void editingStopped(ChangeEvent event)
{
- // TODO Auto-generated method stub
-
+ firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
+ null, null);
}
/**
@@ -784,154 +1479,324 @@ public class JTable
}
}
+ /**
+ * Returns the row number of an accessible child (cell) with the specified
+ * index.
+ *
+ * @param index the index of the cell of which the row number is queried
+ *
+ * @return the row number of an accessible child (cell) with the specified
+ * index
+ */
public int getAccessibleRow(int index)
{
- // TODO Auto-generated method stub
- return 0;
+ return getAccessibleRowAtIndex(index);
}
+ /**
+ * Returns the column number of an accessible child (cell) with the
+ * specified index.
+ *
+ * @param index the index of the cell of which the column number is queried
+ *
+ * @return the column number of an accessible child (cell) with the
+ * specified index
+ */
public int getAccessibleColumn(int index)
{
- // TODO Auto-generated method stub
- return 0;
+ return getAccessibleColumnAtIndex(index);
}
+ /**
+ * Returns the index of the accessible child at the specified row and
+ * column.
+ *
+ * @param r the row number
+ * @param c the column number
+ *
+ * @return the index of the accessible child at the specified row and
+ * column
+ */
public int getAccessibleIndex(int r, int c)
{
- // TODO Auto-generated method stub
- return 0;
+ return getAccessibleIndexAt(r, c);
}
+ /**
+ * Returns the caption of the table.
+ *
+ * @return the caption of the table
+ *
+ * @see #setAccessibleCaption(Accessible)
+ */
public Accessible getAccessibleCaption()
{
- // TODO Auto-generated method stub
- return null;
+ return caption;
}
- public void setAccessibleCaption(Accessible caption)
+ /**
+ * Sets the caption for the table.
+ *
+ * @param c the caption to set
+ */
+ public void setAccessibleCaption(Accessible c)
{
- // TODO Auto-generated method stub
-
+ caption = c;
}
+ /**
+ * Returns the summary for the table.
+ *
+ * @return the summary for the table
+ */
public Accessible getAccessibleSummary()
{
- // TODO Auto-generated method stub
- return null;
+ return summary;
}
- public void setAccessibleSummary(Accessible summary)
+ /**
+ * Sets the summary for the table.
+ *
+ * @param s the summary to set
+ */
+ public void setAccessibleSummary(Accessible s)
{
- // TODO Auto-generated method stub
-
+ summary = s;
}
+ /**
+ * Returns the number of rows in the table.
+ *
+ * @return the number of rows in the table
+ */
public int getAccessibleRowCount()
{
- // TODO Auto-generated method stub
- return 0;
+ return getRowCount();
}
+ /**
+ * Returns the number of columns in the table.
+ *
+ * @return the number of columns in the table
+ */
public int getAccessibleColumnCount()
{
- // TODO Auto-generated method stub
- return 0;
+ return getColumnCount();
}
+ /**
+ * Returns the accessible child (table cell) at the specified row and
+ * column.
+ *
+ * @param r the row number
+ * @param c the column number
+ *
+ * @return the accessible child (table cell) at the specified row and
+ * column
+ */
public Accessible getAccessibleAt(int r, int c)
{
- // TODO Auto-generated method stub
- return null;
+ return getAccessibleChild(r * getAccessibleColumnCount() + c);
}
+ /**
+ * Returns the number of rows that the specified cell occupies. The
+ * standard table cells only occupy one row, so we return <code>1</code>
+ * here.
+ *
+ * @param r the row number
+ * @param c the column number
+ *
+ * @return the number of rows that the specified cell occupies
+ */
public int getAccessibleRowExtentAt(int r, int c)
{
- // TODO Auto-generated method stub
- return 0;
+ return 1;
}
+ /**
+ * Returns the number of columns that the specified cell occupies. The
+ * standard table cells only occupy one column, so we return <code>1</code>
+ * here.
+ *
+ * @param r the row number
+ * @param c the column number
+ *
+ * @return the number of rows that the specified cell occupies
+ */
public int getAccessibleColumnExtentAt(int r, int c)
{
- // TODO Auto-generated method stub
- return 0;
+ return 1;
}
+ /**
+ * Returns the accessible row header.
+ *
+ * @return the accessible row header
+ */
public AccessibleTable getAccessibleRowHeader()
{
- // TODO Auto-generated method stub
+ // The RI seems to always return null here, so do we.
return null;
}
+ /**
+ * Sets the accessible row header.
+ *
+ * @param header the header to set
+ */
public void setAccessibleRowHeader(AccessibleTable header)
{
- // TODO Auto-generated method stub
-
+ // In the RI this seems to be a no-op.
}
+ /**
+ * Returns the column header.
+ *
+ * @return the column header, or <code>null</code> if there is no column
+ * header
+ */
public AccessibleTable getAccessibleColumnHeader()
{
- // TODO Auto-generated method stub
- return null;
+ JTableHeader h = getTableHeader();
+ AccessibleTable header = null;
+ if (h != null)
+ header = new AccessibleTableHeader(h);
+ return header;
}
+ /**
+ * Sets the accessible column header. The default implementation doesn't
+ * allow changing the header this way, so this is a no-op.
+ *
+ * @param header the accessible column header to set
+ */
public void setAccessibleColumnHeader(AccessibleTable header)
{
- // TODO Auto-generated method stub
-
+ // The RI doesn't seem to do anything, so we also do nothing.
}
+ /**
+ * Returns the accessible description for the row with the specified index,
+ * or <code>null</code> if no description has been set.
+ *
+ * @param r the row for which the description is queried
+ *
+ * @return the accessible description for the row with the specified index,
+ * or <code>null</code> if no description has been set
+ */
public Accessible getAccessibleRowDescription(int r)
{
- // TODO Auto-generated method stub
- return null;
+ Accessible descr = null;
+ if (rowDescriptions != null)
+ descr = rowDescriptions[r];
+ return descr;
}
+ /**
+ * Sets the accessible description for the row with the specified index.
+ *
+ * @param r the row number for which to set the description
+ * @param description the description to set
+ */
public void setAccessibleRowDescription(int r, Accessible description)
{
- // TODO Auto-generated method stub
-
+ if (rowDescriptions == null)
+ rowDescriptions = new Accessible[getAccessibleRowCount()];
+ rowDescriptions[r] = description;
}
+ /**
+ * Returns the accessible description for the column with the specified
+ * index, or <code>null</code> if no description has been set.
+ *
+ * @param c the column for which the description is queried
+ *
+ * @return the accessible description for the column with the specified
+ * index, or <code>null</code> if no description has been set
+ */
public Accessible getAccessibleColumnDescription(int c)
{
- // TODO Auto-generated method stub
- return null;
+ Accessible descr = null;
+ if (columnDescriptions != null)
+ descr = columnDescriptions[c];
+ return descr;
}
+ /**
+ * Sets the accessible description for the column with the specified index.
+ *
+ * @param c the column number for which to set the description
+ * @param description the description to set
+ */
public void setAccessibleColumnDescription(int c, Accessible description)
{
- // TODO Auto-generated method stub
-
+ if (columnDescriptions == null)
+ columnDescriptions = new Accessible[getAccessibleRowCount()];
+ columnDescriptions[c] = description;
}
+ /**
+ * Returns <code>true</code> if the accessible child at the specified
+ * row and column is selected, <code>false</code> otherwise.
+ *
+ * @param r the row number of the child
+ * @param c the column number of the child
+ *
+ * @return <code>true</code> if the accessible child at the specified
+ * row and column is selected, <code>false</code> otherwise
+ */
public boolean isAccessibleSelected(int r, int c)
{
- // TODO Auto-generated method stub
- return false;
+ return isCellSelected(r, c);
}
+ /**
+ * Returns <code>true</code> if the row with the specified index is
+ * selected, <code>false</code> otherwise.
+ *
+ * @param r the row number
+ *
+ * @return <code>true</code> if the row with the specified index is
+ * selected, <code>false</code> otherwise
+ */
public boolean isAccessibleRowSelected(int r)
{
- // TODO Auto-generated method stub
- return false;
+ return isRowSelected(r);
}
+ /**
+ * Returns <code>true</code> if the column with the specified index is
+ * selected, <code>false</code> otherwise.
+ *
+ * @param c the column number
+ *
+ * @return <code>true</code> if the column with the specified index is
+ * selected, <code>false</code> otherwise
+ */
public boolean isAccessibleColumnSelected(int c)
{
- // TODO Auto-generated method stub
- return false;
+ return isColumnSelected(c);
}
+ /**
+ * Returns the indices of all selected rows.
+ *
+ * @return the indices of all selected rows
+ */
public int[] getSelectedAccessibleRows()
{
- // TODO Auto-generated method stub
- return null;
+ return getSelectedRows();
}
+ /**
+ * Returns the indices of all selected columns.
+ *
+ * @return the indices of all selected columns
+ */
public int[] getSelectedAccessibleColumns()
{
- // TODO Auto-generated method stub
- return null;
+ return getSelectedColumns();
}
/**
@@ -1017,7 +1882,17 @@ public class JTable
/**
* The CheckBox that is used for rendering.
*/
- private final JCheckBox checkBox = new JCheckBox();
+ private final JCheckBox checkBox;
+
+ /**
+ * Creates a new checkbox based boolean cell renderer. The checkbox is
+ * centered by default.
+ */
+ BooleanCellRenderer()
+ {
+ checkBox = new JCheckBox();
+ checkBox.setHorizontalAlignment(SwingConstants.CENTER);
+ }
/**
* Get the check box.
@@ -1223,6 +2098,12 @@ public class JTable
private class IconCellRenderer
extends DefaultTableCellRenderer
{
+ IconCellRenderer()
+ {
+ setHorizontalAlignment(SwingConstants.CENTER);
+ }
+
+
/**
* Returns the component that is used for rendering the value.
*
@@ -1272,17 +2153,6 @@ public class JTable
{
setBorder(BorderFactory.createLineBorder(getGridColor(), 2));
}
-
- /**
- * With not this method overridden, the scroll pane scrolls to the
- * top left cornec (untranslated position of the caret) after the first
- * keystroke.
- */
- public void scrollRectToVisible(Rectangle r)
- {
- // Do nothing here. If the editing session starts outside the visible
- // bounds, the editCellAt will scroll.
- }
}
@@ -1335,14 +2205,14 @@ public class JTable
* {@link TableCellEditor} objects. This table is consulted by the
* FIXME
*/
- protected Hashtable defaultEditorsByColumnClass;
+ protected Hashtable defaultEditorsByColumnClass = new Hashtable();
/**
* A table mapping {@link java.lang.Class} objects to
* {@link TableCellEditor} objects. This table is consulted by the
* FIXME
*/
- protected Hashtable defaultRenderersByColumnClass;
+ protected Hashtable defaultRenderersByColumnClass = new Hashtable();
/**
* The column that is edited, -1 if the table is not edited currently.
@@ -1588,6 +2458,27 @@ public class JTable
private boolean clientRowHeightSet = false;
/**
+ * Stores the sizes and positions of each row, when using non-uniform row
+ * heights. Initially the height of all rows is equal and stored in
+ * {link #rowHeight}. However, when an application calls
+ * {@link #setRowHeight(int,int)}, the table switches to non-uniform
+ * row height mode which stores the row heights in the SizeSequence
+ * object instead.
+ *
+ * @see #setRowHeight(int)
+ * @see #getRowHeight()
+ * @see #getRowHeight(int)
+ * @see #setRowHeight(int, int)
+ */
+ private SizeSequence rowHeights;
+
+ /**
+ * This editor serves just a marker that the value must be simply changed to
+ * the opposite one instead of starting the editing session.
+ */
+ private transient TableCellEditor booleanInvertingEditor;
+
+ /**
* Creates a new <code>JTable</code> instance.
*/
public JTable ()
@@ -1719,15 +2610,9 @@ public class JTable
if (autoCreateColumnsFromModel)
createDefaultColumnsFromModel();
this.columnModel.addColumnModelListener(this);
-
- this.defaultRenderersByColumnClass = new Hashtable();
- createDefaultRenderers();
-
- this.defaultEditorsByColumnClass = new Hashtable();
- createDefaultEditors();
this.autoResizeMode = AUTO_RESIZE_SUBSEQUENT_COLUMNS;
- this.rowHeight = 16;
+ setRowHeight(16);
this.rowMargin = 1;
this.rowSelectionAllowed = true;
// this.accessibleContext = new AccessibleJTable();
@@ -1773,7 +2658,10 @@ public class JTable
protected void createDefaultEditors()
{
JCheckBox box = new BooleanCellRenderer().getCheckBox();
- setDefaultEditor(Boolean.class, new DefaultCellEditor(box));
+ box.setBorder(BorderFactory.createLineBorder(getGridColor(), 2));
+ box.setBorderPainted(true);
+ booleanInvertingEditor = new DefaultCellEditor(box);
+ setDefaultEditor(Boolean.class, booleanInvertingEditor);
}
/**
@@ -1871,6 +2759,8 @@ public class JTable
*/
public void columnMoved (TableColumnModelEvent event)
{
+ if (isEditing())
+ editingCanceled(null);
revalidate();
repaint();
}
@@ -1891,12 +2781,6 @@ public class JTable
*/
public void columnSelectionChanged (ListSelectionEvent event)
{
- // Does not make sense for the table with the single column.
- if (getColumnCount() < 2)
- return;
-
- int x0 = 0;
-
// We must limit the indices to the bounds of the JTable's model, because
// we might get values of -1 or greater then columnCount in the case
// when columns get removed.
@@ -1904,17 +2788,39 @@ public class JTable
event.getFirstIndex()));
int idxn = Math.max(0, Math.min(getColumnCount() - 1,
event.getLastIndex()));
- int i;
- for (i = 0; i < idx0; i++)
- x0 += columnModel.getColumn(i).getWidth();
-
- int xn = x0;
-
- for (i = idx0; i <= idxn; i++)
- xn += columnModel.getColumn(i).getWidth();
-
- repaint(x0, 0, xn-x0, getHeight());
+ int minRow = 0;
+ int maxRow = getRowCount() - 1;
+ if (getRowSelectionAllowed())
+ {
+ minRow = selectionModel.getMinSelectionIndex();
+ maxRow = selectionModel.getMaxSelectionIndex();
+ int leadRow = selectionModel.getLeadSelectionIndex();
+ if (minRow == -1 && maxRow == -1)
+ {
+ minRow = leadRow;
+ maxRow = leadRow;
+ }
+ else
+ {
+ // In this case we need to repaint also the range to leadRow, not
+ // only between min and max.
+ if (leadRow != -1)
+ {
+ minRow = Math.min(minRow, leadRow);
+ maxRow = Math.max(maxRow, leadRow);
+ }
+ }
+ }
+ if (minRow != -1 && maxRow != -1)
+ {
+ Rectangle first = getCellRect(minRow, idx0, false);
+ Rectangle last = getCellRect(maxRow, idxn, false);
+ Rectangle dirty = SwingUtilities.computeUnion(first.x, first.y,
+ first.width,
+ first.height, last);
+ repaint(dirty);
+ }
}
/**
@@ -1958,7 +2864,13 @@ public class JTable
// changed and the flag autoCreateColumnsFromModel is set
if ((event == null || (event.getFirstRow() == TableModelEvent.HEADER_ROW))
&& autoCreateColumnsFromModel)
- createDefaultColumnsFromModel();
+ {
+ rowHeights = null;
+ if (getAutoCreateColumnsFromModel())
+ createDefaultColumnsFromModel();
+ resizeAndRepaint();
+ return;
+ }
// If the structure changes, we need to revalidate, since that might
// affect the size parameters of the JTable. Otherwise we only need
@@ -1975,6 +2887,8 @@ public class JTable
if (last < 0)
last = getRowCount() - 1;
selectionModel.insertIndexInterval(first, last - first + 1, true);
+ if (rowHeights != null)
+ rowHeights.insertEntries(first, last - first + 1, rowHeight);
}
revalidate();
}
@@ -1990,6 +2904,8 @@ public class JTable
if (last < 0)
last = getRowCount() - 1;
selectionModel.removeIndexInterval(first, last);
+ if (rowHeights != null)
+ rowHeights.removeEntries(first, last - first + 1);
}
if (dataModel.getRowCount() == 0)
clearSelection();
@@ -2004,14 +2920,19 @@ public class JTable
*/
public void valueChanged (ListSelectionEvent event)
{
- // Does not make sense for the table with the single row.
- if (getRowCount() < 2)
- return;
+ // If we are in the editing process, end the editing session.
+ if (isEditing())
+ editingStopped(null);
- int y_gap = rowMargin;
- int y0 = (getRowHeight() + y_gap) * (event.getFirstIndex());
- int yn = (getRowHeight() + y_gap) * (event.getLastIndex()+1);
- repaint(0, y0, getWidth(), yn-y0);
+ // Repaint the changed region.
+ int first = Math.max(0, Math.min(getRowCount() - 1, event.getFirstIndex()));
+ int last = Math.max(0, Math.min(getRowCount() - 1, event.getLastIndex()));
+ Rectangle rect1 = getCellRect(first, 0, false);
+ Rectangle rect2 = getCellRect(last, getColumnCount() - 1, false);
+ Rectangle dirty = SwingUtilities.computeUnion(rect2.x, rect2.y,
+ rect2.width, rect2.height,
+ rect1);
+ repaint(dirty);
}
/**
@@ -2053,10 +2974,16 @@ public class JTable
if (point != null)
{
int nrows = getRowCount();
- int height = getRowHeight() + getRowMargin();
+ int r;
int y = point.y;
+ if (rowHeights == null)
+ {
+ int height = getRowHeight();
+ r = y / height;
+ }
+ else
+ r = rowHeights.getIndex(y);
- int r = y / height;
if (r < 0 || r >= nrows)
return -1;
else
@@ -2086,27 +3013,70 @@ public class JTable
int column,
boolean includeSpacing)
{
- int height = getRowHeight(row);
- int width = columnModel.getColumn(column).getWidth();
- int x_gap = columnModel.getColumnMargin();
- int y_gap = rowMargin;
+ Rectangle cellRect = new Rectangle(0, 0, 0, 0);
- column = Math.max(0, Math.min(column, getColumnCount() - 1));
- row = Math.max(0, Math.min(row, getRowCount() - 1));
-
- int x = 0;
- int y = (height + y_gap) * row;
+ // Check for valid range vertically.
+ if (row >= getRowCount())
+ {
+ cellRect.height = getHeight();
+ }
+ else if (row >= 0)
+ {
+ cellRect.height = getRowHeight(row);
+ if (rowHeights == null)
+ cellRect.y = row * cellRect.height;
+ else
+ cellRect.y = rowHeights.getPosition(row);
- for (int i = 0; i < column; ++i)
- x += columnModel.getColumn(i).getWidth();
-
- Rectangle rect = new Rectangle();
+ if (! includeSpacing)
+ {
+ // The rounding here is important.
+ int rMargin = getRowMargin();
+ cellRect.y += rMargin / 2;
+ cellRect.height -= rMargin;
+ }
+ }
+ // else row < 0, y = height = 0
- if (includeSpacing)
- rect.setBounds(x, y, width, height +y_gap);
+ // Check for valid range horizontally.
+ if (column < 0)
+ {
+ if (! getComponentOrientation().isLeftToRight())
+ {
+ cellRect.x = getWidth();
+ }
+ }
+ else if (column >= getColumnCount())
+ {
+ if (getComponentOrientation().isLeftToRight())
+ {
+ cellRect.x = getWidth();
+ }
+ }
else
- rect.setBounds(x, y, width - x_gap, height);
- return rect;
+ {
+ TableColumnModel tcm = getColumnModel();
+ if (getComponentOrientation().isLeftToRight())
+ {
+ for (int i = 0; i < column; i++)
+ cellRect.x += tcm.getColumn(i).getWidth();
+ }
+ else
+ {
+ for (int i = tcm.getColumnCount() - 1; i > column; i--)
+ cellRect.x += tcm.getColumn(i).getWidth();
+ }
+ cellRect.width = tcm.getColumn(column).getWidth();
+ if (! includeSpacing)
+ {
+ // The rounding here is important.
+ int cMargin = tcm.getColumnMargin();
+ cellRect.x += cMargin / 2;
+ cellRect.width -= cMargin;
+ }
+ }
+
+ return cellRect;
}
public void clearSelection()
@@ -2354,7 +3324,6 @@ public class JTable
int row,
int column)
{
-
boolean rowSelAllowed = getRowSelectionAllowed();
boolean colSelAllowed = getColumnSelectionAllowed();
boolean isSel = false;
@@ -2418,9 +3387,10 @@ public class JTable
*/
public int getRowHeight(int row)
{
- // FIXME: return the height of the specified row
- // which may be different from the general rowHeight
- return rowHeight;
+ int rh = rowHeight;
+ if (rowHeights != null)
+ rh = rowHeights.getSize(row);
+ return rh;
}
@@ -2626,6 +3596,17 @@ public class JTable
*/
public AccessibleContext getAccessibleContext()
{
+ if (accessibleContext == null)
+ {
+ AccessibleJTable ctx = new AccessibleJTable();
+ addPropertyChangeListener(ctx);
+ TableColumnModel tcm = getColumnModel();
+ tcm.addColumnModelListener(ctx);
+ tcm.getSelectionModel().addListSelectionListener(ctx);
+ getSelectionModel().addListSelectionListener(ctx);
+
+ accessibleContext = ctx;
+ }
return accessibleContext;
}
@@ -2780,9 +3761,14 @@ public class JTable
}
/**
- * Set the value of the {@link #rowHeight} property.
+ * Sets the height for all rows in the table. If you want to change the
+ * height of a single row instead, use {@link #setRowHeight(int, int)}.
*
- * @param r The new value of the rowHeight property
+ * @param r the height to set for all rows
+ *
+ * @see #getRowHeight()
+ * @see #setRowHeight(int, int)
+ * @see #getRowHeight(int)
*/
public void setRowHeight(int r)
{
@@ -2792,21 +3778,24 @@ public class JTable
clientRowHeightSet = true;
rowHeight = r;
+ rowHeights = null;
revalidate();
repaint();
}
/**
- * Sets the value of the rowHeight property for the specified
- * row.
+ * Sets the height of a single row in the table.
*
- * @param rh is the new rowHeight
- * @param row is the row to change the rowHeight of
+ * @param rh the new row height
+ * @param row the row to change the height of
*/
public void setRowHeight(int row, int rh)
{
- setRowHeight(rh);
- // FIXME: not implemented
+ if (rowHeights == null)
+ {
+ rowHeights = new SizeSequence(getRowCount(), rowHeight);
+ }
+ rowHeights.setSize(row, rh);
}
/**
@@ -2878,6 +3867,10 @@ public class JTable
// Add table as TableModelListener to new model.
dataModel.addTableModelListener(this);
+ // Notify the tableChanged method.
+ tableChanged(new TableModelEvent(dataModel,
+ TableModelEvent.HEADER_ROW));
+
// Automatically create columns.
if (autoCreateColumnsFromModel)
createDefaultColumnsFromModel();
@@ -3210,7 +4203,7 @@ public class JTable
public void doLayout()
{
TableColumn resizingColumn = null;
-
+
int ncols = getColumnCount();
if (ncols < 1)
return;
@@ -3236,7 +4229,7 @@ public class JTable
{
TableColumn col;
TableColumn [] cols;
-
+
switch (getAutoResizeMode())
{
case AUTO_RESIZE_LAST_COLUMN:
@@ -3298,20 +4291,44 @@ public class JTable
TableColumn [] cols = new TableColumn[ncols];
for (int i = 0; i < ncols; ++i)
cols[i] = columnModel.getColumn(i);
- distributeSpill(cols, spill);
+ distributeSpill(cols, spill);
}
if (editorComp!=null)
moveToCellBeingEdited(editorComp);
- // Repaint fixes the invalid view after the first keystroke if the cell
- // editing is started immediately after the program start or cell
- // resizing.
- repaint();
- if (tableHeader!=null)
- tableHeader.repaint();
+ int leftBoundary = getLeftResizingBoundary();
+ int width = getWidth() - leftBoundary;
+ repaint(leftBoundary, 0, width, getHeight());
+ if (tableHeader != null)
+ tableHeader.repaint(leftBoundary, 0, width, tableHeader.getHeight());
+ }
+
+ /**
+ * Get the left boundary of the rectangle which changes during the column
+ * resizing.
+ */
+ int getLeftResizingBoundary()
+ {
+ if (tableHeader == null || getAutoResizeMode() == AUTO_RESIZE_ALL_COLUMNS)
+ return 0;
+ else
+ {
+ TableColumn resizingColumn = tableHeader.getResizingColumn();
+ if (resizingColumn == null)
+ return 0;
+
+ int rc = convertColumnIndexToView(resizingColumn.getModelIndex());
+ int p = 0;
+
+ for (int i = 0; i < rc; i++)
+ p += columnModel.getColumn(i).getWidth();
+
+ return p;
+ }
}
+
/**
* @deprecated Replaced by <code>doLayout()</code>
*/
@@ -3351,6 +4368,10 @@ public class JTable
public void setUI(TableUI ui)
{
super.setUI(ui);
+ // The editors and renderers must be recreated because they constructors
+ // may use the look and feel properties.
+ createDefaultEditors();
+ createDefaultRenderers();
}
public void updateUI()
@@ -3567,6 +4588,10 @@ public class JTable
*/
public void selectAll()
{
+ // The table is empty - nothing to do!
+ if (getRowCount() == 0 || getColumnCount() == 0)
+ return;
+
// rowLead and colLead store the current lead selection indices
int rowLead = selectionModel.getLeadSelectionIndex();
int colLead = getColumnModel().getSelectionModel().getLeadSelectionIndex();
@@ -3716,30 +4741,47 @@ public class JTable
/**
* Programmatically starts editing the specified cell.
- *
+ *
* @param row the row of the cell to edit.
* @param column the column of the cell to edit.
*/
- public boolean editCellAt (int row, int column)
+ public boolean editCellAt(int row, int column)
{
// Complete the previous editing session, if still active.
if (isEditing())
editingStopped(new ChangeEvent("editingStopped"));
-
- editingRow = row;
- editingColumn = column;
- setCellEditor(getCellEditor(row, column));
- editorComp = prepareEditor(cellEditor, row, column);
+ TableCellEditor editor = getCellEditor(row, column);
- // Remove the previous editor components, if present. Only one
- // editor component at time is allowed in the table.
- removeAll();
- add(editorComp);
- moveToCellBeingEdited(editorComp);
- scrollRectToVisible(editorComp.getBounds());
- editorComp.requestFocusInWindow();
- return true;
+ // The boolean values are inverted by the single click without the
+ // real editing session.
+ if (editor == booleanInvertingEditor && isCellEditable(row, column))
+ {
+ if (Boolean.TRUE.equals(getValueAt(row, column)))
+ setValueAt(Boolean.FALSE, row, column);
+ else
+ setValueAt(Boolean.TRUE, row, column);
+ return false;
+ }
+ else
+ {
+ editingRow = row;
+ editingColumn = column;
+
+ setCellEditor(editor);
+ editorComp = prepareEditor(cellEditor, row, column);
+
+ // Remove the previous editor components, if present. Only one
+ // editor component at time is allowed in the table.
+ removeAll();
+ add(editorComp);
+ moveToCellBeingEdited(editorComp);
+ scrollRectToVisible(editorComp.getBounds());
+ editorComp.requestFocusInWindow();
+
+ // Deliver the should select event.
+ return editor.shouldSelectCell(null);
+ }
}
/**
diff --git a/javax/swing/JTree.java b/javax/swing/JTree.java
index e3b8b7e7c..31e9a8aa9 100644
--- a/javax/swing/JTree.java
+++ b/javax/swing/JTree.java
@@ -1142,9 +1142,9 @@ public class JTree extends JComponent implements Scrollable, Accessible
public boolean isLeaf()
{
- return (childValue == null || !(childValue instanceof Hashtable
- || childValue instanceof Vector || childValue.getClass()
- .isArray()));
+ return childValue == null || !(childValue instanceof Hashtable
+ || childValue instanceof Vector
+ || childValue.getClass().isArray());
}
public static void createChildren(DefaultMutableTreeNode parent,
@@ -2316,7 +2316,7 @@ public class JTree extends JComponent implements Scrollable, Accessible
selectionModel.addSelectionPath(path);
}
- if (oldValue!=null)
+ if (oldValue != null)
repaint(getPathBounds(oldValue));
firePropertyChange(LEAD_SELECTION_PATH_PROPERTY, oldValue, path);
diff --git a/javax/swing/JViewport.java b/javax/swing/JViewport.java
index 2b5d1cd5a..7cf393996 100644
--- a/javax/swing/JViewport.java
+++ b/javax/swing/JViewport.java
@@ -877,7 +877,7 @@ public class JViewport extends JComponent implements Accessible
{
// If the image has not been scrolled at all, only the changed
// clip must be updated in the buffer.
- if (dx==0 && dy==0)
+ if (dx == 0 && dy == 0)
g2.setClip(g.getClip());
paintSimple(g2);
diff --git a/javax/swing/KeyboardManager.java b/javax/swing/KeyboardManager.java
index 4f778f733..f7ac9496c 100644
--- a/javax/swing/KeyboardManager.java
+++ b/javax/swing/KeyboardManager.java
@@ -46,6 +46,7 @@ import java.awt.event.KeyEvent;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
+import java.util.WeakHashMap;
/**
* This class maintains a mapping from top-level containers to a
@@ -65,7 +66,7 @@ class KeyboardManager
* A mapping between top level containers and Hashtables that
* map KeyStrokes to Components.
*/
- Hashtable topLevelLookup = new Hashtable();
+ WeakHashMap topLevelLookup = new WeakHashMap();
/**
* A mapping between top level containers and Vectors of JMenuBars
diff --git a/javax/swing/ListSelectionModel.java b/javax/swing/ListSelectionModel.java
index 324c05643..499362d04 100644
--- a/javax/swing/ListSelectionModel.java
+++ b/javax/swing/ListSelectionModel.java
@@ -1,5 +1,5 @@
/* ListSelectionModel.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,59 +38,295 @@ exception statement from your version. */
package javax.swing;
+import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
/**
- * The model that is used in {@link JList} to define the selected/not-selected
- * cells of that list.
+ * A model that tracks the selection status of a list of items. Each item in
+ * the list is identified by a zero-based index only, so the model can be used
+ * to track the selection status of any type of list. The model
+ * supports three modes:
+ * <ul>
+ * <li><code>SINGLE_SELECTION</code> - only one item in the list may be
+ * selected;</li>
+ * <li><code>SINGLE_INTERVAL_SELECTION</code> - only one interval in the list
+ * may be selected;</li>
+ * <li><code>MULTIPLE_INTERVAL_SELECTION</code> - any combination of items in
+ * the list may be selected.</li>
+ * </ul>
+ * The model uses an event notification mechanism to notify listeners (see
+ * {@link ListSelectionListener}) about updates to the selection model.
+ * <p>
+ * This model is used to track row selections in the {@link JList} component,
+ * and row and column selections in the {@link JTable} component.
*/
public interface ListSelectionModel
{
-
+
+ /**
+ * A selection mode in which only one item can be selected.
+ *
+ * @see #setSelectionMode(int)
+ */
int SINGLE_SELECTION = 0;
+ /**
+ * A selection mode in which a single interval can be selected (an interval
+ * is a range containing one or more contiguous items).
+ *
+ * @see #setSelectionMode(int)
+ */
int SINGLE_INTERVAL_SELECTION = 1;
+ /**
+ * A selection mode in which any combination of items can be selected.
+ *
+ * @see #setSelectionMode(int)
+ */
int MULTIPLE_INTERVAL_SELECTION = 2;
- void setSelectionMode(int a);
-
+ /**
+ * Sets the selection mode.
+ * <p>
+ * FIXME: The spec is silent about what happens to existing selections, for
+ * example when changing from an interval selection to single selection.
+ *
+ * @param mode one of {@link #SINGLE_SELECTION},
+ * {@link #SINGLE_INTERVAL_SELECTION} and
+ * {@link #MULTIPLE_INTERVAL_SELECTION}.
+ *
+ * @see #getSelectionMode()
+ *
+ * @throws IllegalArgumentException if <code>mode</code> is not one of the
+ * specified values.
+ */
+ void setSelectionMode(int mode);
+
+ /**
+ * Returns the selection mode, which is one of {@link #SINGLE_SELECTION},
+ * {@link #SINGLE_INTERVAL_SELECTION} and
+ * {@link #MULTIPLE_INTERVAL_SELECTION}.
+ *
+ * @return The selection mode.
+ *
+ * @see #setSelectionMode(int)
+ */
int getSelectionMode();
+ /**
+ * Clears the current selection from the model. If the selection state
+ * changes (that is, the existing selection is non-empty) a
+ * {@link ListSelectionEvent} should be sent to all registered listeners.
+ * <p>
+ * FIXME: what happens to the anchor and lead selection indices (the spec
+ * is silent about this)? See:
+ * <p>
+ * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4334792
+ */
void clearSelection();
+ /**
+ * Returns the lowest selected index, or <code>-1</code> if there is no
+ * selection.
+ *
+ * @return The lowest selected index.
+ *
+ * @see #getMaxSelectionIndex()
+ */
int getMinSelectionIndex();
+ /**
+ * Returns the highest selected index, or <code>-1</code> if there is no
+ * selection.
+ *
+ * @return The highest selected index.
+ *
+ * @see #getMinSelectionIndex()
+ */
int getMaxSelectionIndex();
- boolean isSelectedIndex(int a);
-
+ /**
+ * Returns <code>true</code> if the specified item is selected, and
+ * <code>false</code> otherwise. Special note: if <code>index</code> is
+ * negative, this method should return <code>false</code> (no exception
+ * should be thrown).
+ *
+ * @param index the item index (zero-based).
+ *
+ * @return <code>true</code> if the specified item is selected, and
+ * <code>false</code> otherwise.
+ */
+ boolean isSelectedIndex(int index);
+
+ /**
+ * Returns <code>true</code> if there is no selection, and <code>false</code>
+ * otherwise.
+ *
+ * @return <code>true</code> if there is no selection, and
+ * <code>false</code> otherwise.
+ */
boolean isSelectionEmpty();
- void setSelectionInterval(int index0, int index1);
-
- void addSelectionInterval(int index0, int index1);
-
- void removeSelectionInterval(int index0, int index1);
-
+ /**
+ * Sets the selection interval to the specified range (note that
+ * <code>anchor</code> can be less than, equal to, or greater than
+ * <code>lead</code>). If this results in the selection being changed,
+ * a {@link ListSelectionEvent} is sent to all registered listeners.
+ * <p>
+ * If the selection mode is {@link #SINGLE_SELECTION}, only the
+ * <code>lead</code> item is selected.
+ *
+ * @param anchor the anchor index.
+ * @param lead the lead index.
+ */
+ void setSelectionInterval(int anchor, int lead);
+
+ /**
+ * Marks the items in the specified interval as selected. The behaviour of
+ * this method depends on the selection mode:
+ * <ul>
+ * <li><code>SINGLE_SELECTION</code> - only the <code>lead</code> item is
+ * selected;</li>
+ * <li><code>SINGLE_INTERVAL_SELECTION</code> - the existing selection
+ * interval is replaced by the specified interval;</li>
+ * <li><code>MULTIPLE_INTERVAL_SELECTION</code> - the specified interval is
+ * merged into the currently selected intervals.</li>
+ * </ul>
+ * Note that <code>anchor</code> can be less than, equal to, or greater than
+ * <code>lead</code>.
+ *
+ * @param anchor the index of the anchor item
+ * @param lead the index of the lead item.
+ */
+ void addSelectionInterval(int anchor, int lead);
+
+ /**
+ * Marks the items in the specified interval as not selected. The behaviour
+ * of this method depends on the selection mode:
+ * <ul>
+ * <li><code>SINGLE_SELECTION</code> - XXX;</li>
+ * <li><code>SINGLE_INTERVAL_SELECTION</code> - XXX;</li>
+ * <li><code>MULTIPLE_INTERVAL_SELECTION</code> - XXX.</li>
+ * </ul>
+ * Note that <code>anchor</code> can be less than, equal to, or greater than
+ * <code>lead</code>.
+ *
+ * @param anchor the index of the anchor item
+ * @param lead the index of the lead item.
+ */
+ void removeSelectionInterval(int anchor, int lead);
+
+ /**
+ * Inserts a new interval containing <code>length</code> items at the
+ * specified <code>index</code> (the <code>before</code> flag indicates
+ * whether the range is inserted before or after the existing item at
+ * <code>index</code>).
+ *
+ * FIXME: What is the selection status of the new items? Bug 4870694.
+ * FIXME: What event is generated?
+ *
+ * @param index the index of the item.
+ * @param length the number of items in the interval to be inserted.
+ * @param before if <code>true</code>, the interval should be inserted
+ * before <code>index</code>, otherwise it is inserted after.
+ *
+ * @see #removeIndexInterval(int, int)
+ */
void insertIndexInterval(int index, int length, boolean before);
+ /**
+ * Removes the items in the specified range (inclusive) from the selection
+ * model. This method should be called when an interval is deleted from
+ * the underlying list.
+ *
+ * FIXME: what happens to the lead and anchor indices if they are part of
+ * the range that is removed?
+ * FIXME: what event is generated
+ *
+ * @param index0 XXX
+ * @param index1 XXX
+ *
+ * @see #insertIndexInterval(int, int, boolean)
+ */
void removeIndexInterval(int index0, int index1);
+ /**
+ * Returns the index of the anchor item.
+ *
+ * @return The index of the anchor item.
+ *
+ * @see #setAnchorSelectionIndex(int)
+ */
int getAnchorSelectionIndex();
+ /**
+ * Sets the index of the anchor item.
+ *
+ * @param index the item index.
+ *
+ * @see #getAnchorSelectionIndex()
+ */
void setAnchorSelectionIndex(int index);
+ /**
+ * Returns the index of the lead item.
+ *
+ * @return The index of the lead item.
+ *
+ * @see #setLeadSelectionIndex(int)
+ */
int getLeadSelectionIndex();
+ /**
+ * Sets the index of the lead item.
+ *
+ * @param index the item index.
+ *
+ * @see #getLeadSelectionIndex()
+ */
void setLeadSelectionIndex(int index);
+ /**
+ * Sets the flag that is passed to listeners for each change notification.
+ * If a sequence of changes is made to the selection model, this flag should
+ * be set to <code>true</code> at the start of the sequence, and
+ * <code>false</code> for the last change - this gives listeners the option
+ * to ignore interim changes if that is more efficient.
+ *
+ * @param valueIsAdjusting the flag value.
+ *
+ * @see #getValueIsAdjusting()
+ */
void setValueIsAdjusting(boolean valueIsAdjusting);
+ /**
+ * Returns a flag that is passed to registered listeners when changes are
+ * made to the model. See the description for
+ * {@link #setValueIsAdjusting(boolean)} for more information.
+ *
+ * @return The flag.
+ */
boolean getValueIsAdjusting();
+ /**
+ * Registers a listener with the model so that it receives notification
+ * of changes to the model.
+ *
+ * @param listener the listener (<code>null</code> ignored).
+ *
+ * @see #removeListSelectionListener(ListSelectionListener)
+ */
void addListSelectionListener(ListSelectionListener listener);
+ /**
+ * Deregisters a listener so that it no longer receives notification of
+ * changes to the model. If the specified listener is not registered with
+ * the model, or is <code>null</code>, this method does nothing.
+ *
+ * @param listener the listener (<code>null</code> ignored).
+ *
+ * @see #addListSelectionListener(ListSelectionListener)
+ */
void removeListSelectionListener(ListSelectionListener listener);
}
diff --git a/javax/swing/ProgressMonitor.java b/javax/swing/ProgressMonitor.java
index 73e36b9ca..28d22e8a6 100644
--- a/javax/swing/ProgressMonitor.java
+++ b/javax/swing/ProgressMonitor.java
@@ -38,8 +38,10 @@ exception statement from your version. */
package javax.swing;
import java.awt.Component;
-import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.accessibility.AccessibleContext;
/**
* <p>Using this class you can easily monitor tasks where you cannot
@@ -62,6 +64,12 @@ import java.awt.event.ActionEvent;
*/
public class ProgressMonitor
{
+
+ /**
+ * The accessible content for this component
+ */
+ protected AccessibleContext accessibleContext;
+
/**
* parentComponent
*/
@@ -439,5 +447,14 @@ public class ProgressMonitor
timestamp = now;
}
}
-
+
+ /**
+ * Gets the accessible context.
+ *
+ * @return the accessible context.
+ */
+ public AccessibleContext getAccessibleContext()
+ {
+ return accessibleContext;
+ }
}
diff --git a/javax/swing/RepaintManager.java b/javax/swing/RepaintManager.java
index 345c348db..4a0581c0e 100644
--- a/javax/swing/RepaintManager.java
+++ b/javax/swing/RepaintManager.java
@@ -47,9 +47,8 @@ import java.awt.Rectangle;
import java.awt.Window;
import java.awt.image.VolatileImage;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
@@ -63,19 +62,20 @@ import java.util.WeakHashMap;
* double buffer surface is used by root components to paint
* themselves.</p>
*
- * <p>In general, painting is very confusing in swing. see <a
+ * <p>See <a
* href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">this
* document</a> for more details.</p>
*
* @author Roman Kennke (kennke@aicas.com)
* @author Graydon Hoare (graydon@redhat.com)
+ * @author Audrius Meskauskas (audriusa@bioinformatics.org)
*/
public class RepaintManager
{
/**
* The current repaint managers, indexed by their ThreadGroups.
*/
- private static WeakHashMap currentRepaintManagers;
+ static WeakHashMap currentRepaintManagers;
/**
* A rectangle object to be reused in damaged regions calculation.
@@ -134,44 +134,6 @@ public class RepaintManager
}
- /**
- * Compares two components using their depths in the component hierarchy.
- * A component with a lesser depth (higher level components) are sorted
- * before components with a deeper depth (low level components). This is used
- * to order paint requests, so that the higher level components are painted
- * before the low level components get painted.
- *
- * @author Roman Kennke (kennke@aicas.com)
- */
- private class ComponentComparator implements Comparator
- {
-
- /**
- * Compares two components.
- *
- * @param o1 the first component
- * @param o2 the second component
- *
- * @return a negative integer, if <code>o1</code> is bigger in than
- * <code>o2</code>, zero, if both are at the same size and a
- * positive integer, if <code>o1</code> is smaller than
- * <code>o2</code>
- */
- public int compare(Object o1, Object o2)
- {
- if (o1 instanceof JComponent && o2 instanceof JComponent)
- {
- JComponent c1 = (JComponent) o1;
- Rectangle d1 = (Rectangle) dirtyComponentsWork.get(c1);
- JComponent c2 = (JComponent) o2;
- Rectangle d2 = (Rectangle) dirtyComponentsWork.get(c2);
- return d2.width * d2.height - d1.width * d1.height;
- }
- throw new ClassCastException("This comparator can only be used with "
- + "JComponents");
- }
- }
-
/**
* A table storing the dirty regions of components. The keys of this
* table are components, the values are rectangles. Each component maps
@@ -187,18 +149,13 @@ public class RepaintManager
* @see #markCompletelyClean
* @see #markCompletelyDirty
*/
- HashMap dirtyComponents;
+ private HashMap dirtyComponents;
/**
* The dirtyComponents which is used in paintDiryRegions to avoid unnecessary
* locking.
*/
- HashMap dirtyComponentsWork;
-
- /**
- * The comparator used for ordered inserting into the repaintOrder list.
- */
- private transient Comparator comparator;
+ private HashMap dirtyComponentsWork;
/**
* A single, shared instance of the helper class. Any methods which mark
@@ -422,6 +379,9 @@ public class RepaintManager
{
if (w <= 0 || h <= 0 || !component.isShowing())
return;
+
+ Component parent = component.getParent();
+
component.computeVisibleRect(rectCache);
SwingUtilities.computeIntersection(x, y, w, h, rectCache);
@@ -485,8 +445,7 @@ public class RepaintManager
public void markCompletelyDirty(JComponent component)
{
Rectangle r = component.getBounds();
- addDirtyRegion(component, r.x, r.y, r.width, r.height);
- component.isCompletelyDirty = true;
+ addDirtyRegion(component, 0, 0, r.width, r.height);
}
/**
@@ -506,7 +465,6 @@ public class RepaintManager
{
dirtyComponents.remove(component);
}
- component.isCompletelyDirty = false;
}
/**
@@ -525,9 +483,13 @@ public class RepaintManager
*/
public boolean isCompletelyDirty(JComponent component)
{
- if (! dirtyComponents.containsKey(component))
- return false;
- return component.isCompletelyDirty;
+ boolean retVal = false;
+ if (dirtyComponents.containsKey(component))
+ {
+ Rectangle dirtyRegion = (Rectangle) dirtyComponents.get(component);
+ retVal = dirtyRegion.equals(SwingUtilities.getLocalBounds(component));
+ }
+ return retVal;
}
/**
@@ -554,8 +516,8 @@ public class RepaintManager
}
/**
- * Repaint all regions of all components which have been marked dirty in
- * the {@link #dirtyComponents} table.
+ * Repaint all regions of all components which have been marked dirty in the
+ * {@link #dirtyComponents} table.
*/
public void paintDirtyRegions()
{
@@ -571,29 +533,76 @@ public class RepaintManager
dirtyComponentsWork = swap;
}
- ArrayList repaintOrder = new ArrayList(dirtyComponentsWork.size());;
- // We sort the components by their size here. This way we have a good
- // chance that painting the bigger components also paints the smaller
- // components and we don't need to paint them twice.
- repaintOrder.addAll(dirtyComponentsWork.keySet());
+ // Compile a set of repaint roots.
+ HashSet repaintRoots = new HashSet();
+ Set components = dirtyComponentsWork.keySet();
+ for (Iterator i = components.iterator(); i.hasNext();)
+ {
+ JComponent dirty = (JComponent) i.next();
+ compileRepaintRoots(dirtyComponentsWork, dirty, repaintRoots);
+ }
- if (comparator == null)
- comparator = new ComponentComparator();
- Collections.sort(repaintOrder, comparator);
repaintUnderway = true;
- for (Iterator i = repaintOrder.iterator(); i.hasNext();)
+ for (Iterator i = repaintRoots.iterator(); i.hasNext();)
{
JComponent comp = (JComponent) i.next();
- // If a component is marked completely clean in the meantime, then skip
- // it.
Rectangle damaged = (Rectangle) dirtyComponentsWork.remove(comp);
if (damaged == null || damaged.isEmpty())
continue;
comp.paintImmediately(damaged);
}
+ dirtyComponentsWork.clear();
repaintUnderway = false;
commitRemainingBuffers();
}
+
+ /**
+ * Compiles a list of components that really get repainted. This is called
+ * once for each component in the dirtyComponents HashMap, each time with
+ * another <code>dirty</code> parameter. This searches up the component
+ * hierarchy of <code>dirty</code> to find the highest parent that is also
+ * marked dirty and merges the dirty regions.
+ *
+ * @param dirtyRegions the dirty regions
+ * @param dirty the component for which to find the repaint root
+ * @param roots the list to which new repaint roots get appended
+ */
+ private void compileRepaintRoots(HashMap dirtyRegions, JComponent dirty,
+ HashSet roots)
+ {
+ Component current = dirty;
+ Component root = dirty;
+
+ // Search the highest component that is also marked dirty.
+ Component parent;
+ while (true)
+ {
+ parent = current.getParent();
+ if (parent == null || !(parent instanceof JComponent))
+ break;
+
+ current = parent;
+ // We can skip to the next up when this parent is not dirty.
+ if (dirtyRegions.containsKey(parent))
+ {
+ root = current;
+ }
+ }
+
+ // Merge the rectangles of the root and the requested component if
+ // the are different.
+ if (root != dirty)
+ {
+ Rectangle dirtyRect = (Rectangle) dirtyRegions.get(dirty);
+ dirtyRect = SwingUtilities.convertRectangle(dirty, dirtyRect, root);
+ Rectangle rootRect = (Rectangle) dirtyRegions.get(root);
+ SwingUtilities.computeUnion(dirtyRect.x, dirtyRect.y, dirtyRect.width,
+ dirtyRect.height, rootRect);
+ }
+
+ // Adds the root to the roots set.
+ roots.add(root);
+ }
/**
* Get an offscreen buffer for painting a component's image. This image
diff --git a/javax/swing/SwingUtilities.java b/javax/swing/SwingUtilities.java
index 9d8e8df38..5d02d9bb3 100644
--- a/javax/swing/SwingUtilities.java
+++ b/javax/swing/SwingUtilities.java
@@ -1446,4 +1446,157 @@ public class SwingUtilities
KeyboardManager km = KeyboardManager.getManager();
return km.processKeyStroke(c, s, ev);
}
+
+ /**
+ * Returns a string representing one of the horizontal alignment codes
+ * defined in the {@link SwingConstants} interface. The following table
+ * lists the constants and return values:
+ * <p>
+ * <table border="0">
+ * <tr>
+ * <th>Code:</th><th>Returned String:</th>
+ * </tr>
+ * <tr>
+ * <td>{@link SwingConstants#CENTER}</td>
+ * <td><code>"CENTER"</code></td>
+ * </tr>
+ * <tr>
+ * <td>{@link SwingConstants#LEFT}</td>
+ * <td><code>"LEFT"</code></td>
+ * </tr>
+ * <tr>
+ * <td>{@link SwingConstants#RIGHT}</td>
+ * <td><code>"RIGHT"</code></td>
+ * </tr>
+ * <tr>
+ * <td>{@link SwingConstants#LEADING}</td>
+ * <td><code>"LEADING"</code></td>
+ * </tr>
+ * <tr>
+ * <td>{@link SwingConstants#TRAILING}</td>
+ * <td><code>"TRAILING"</code></td>
+ * </tr>
+ * </table>
+ * </p>
+ * If the supplied code is not one of those listed, this methods will throw
+ * an {@link IllegalArgumentException}.
+ *
+ * @param code the code.
+ *
+ * @return A string representing the given code.
+ */
+ static String convertHorizontalAlignmentCodeToString(int code)
+ {
+ switch (code)
+ {
+ case SwingConstants.CENTER:
+ return "CENTER";
+ case SwingConstants.LEFT:
+ return "LEFT";
+ case SwingConstants.RIGHT:
+ return "RIGHT";
+ case SwingConstants.LEADING:
+ return "LEADING";
+ case SwingConstants.TRAILING:
+ return "TRAILING";
+ default:
+ throw new IllegalArgumentException("Unrecognised code: " + code);
+ }
+ }
+
+ /**
+ * Returns a string representing one of the vertical alignment codes
+ * defined in the {@link SwingConstants} interface. The following table
+ * lists the constants and return values:
+ * <p>
+ * <table border="0">
+ * <tr>
+ * <th>Code:</th><th>Returned String:</th>
+ * </tr>
+ * <tr>
+ * <td>{@link SwingConstants#CENTER}</td>
+ * <td><code>"CENTER"</code></td>
+ * </tr>
+ * <tr>
+ * <td>{@link SwingConstants#TOP}</td>
+ * <td><code>"TOP"</code></td>
+ * </tr>
+ * <tr>
+ * <td>{@link SwingConstants#BOTTOM}</td>
+ * <td><code>"BOTTOM"</code></td>
+ * </tr>
+ * </table>
+ * </p>
+ * If the supplied code is not one of those listed, this methods will throw
+ * an {@link IllegalArgumentException}.
+ *
+ * @param code the code.
+ *
+ * @return A string representing the given code.
+ */
+ static String convertVerticalAlignmentCodeToString(int code)
+ {
+ switch (code)
+ {
+ case SwingConstants.CENTER:
+ return "CENTER";
+ case SwingConstants.TOP:
+ return "TOP";
+ case SwingConstants.BOTTOM:
+ return "BOTTOM";
+ default:
+ throw new IllegalArgumentException("Unrecognised code: " + code);
+ }
+ }
+
+ /**
+ * Returns a string representing one of the default operation codes
+ * defined in the {@link WindowConstants} interface. The following table
+ * lists the constants and return values:
+ * <p>
+ * <table border="0">
+ * <tr>
+ * <th>Code:</th><th>Returned String:</th>
+ * </tr>
+ * <tr>
+ * <td>{@link WindowConstants#DO_NOTHING_ON_CLOSE}</td>
+ * <td><code>"DO_NOTHING_ON_CLOSE"</code></td>
+ * </tr>
+ * <tr>
+ * <td>{@link WindowConstants#HIDE_ON_CLOSE}</td>
+ * <td><code>"HIDE_ON_CLOSE"</code></td>
+ * </tr>
+ * <tr>
+ * <td>{@link WindowConstants#DISPOSE_ON_CLOSE}</td>
+ * <td><code>"DISPOSE_ON_CLOSE"</code></td>
+ * </tr>
+ * <tr>
+ * <td>{@link WindowConstants#EXIT_ON_CLOSE}</td>
+ * <td><code>"EXIT_ON_CLOSE"</code></td>
+ * </tr>
+ * </table>
+ * </p>
+ * If the supplied code is not one of those listed, this method will throw
+ * an {@link IllegalArgumentException}.
+ *
+ * @param code the code.
+ *
+ * @return A string representing the given code.
+ */
+ static String convertWindowConstantToString(int code)
+ {
+ switch (code)
+ {
+ case WindowConstants.DO_NOTHING_ON_CLOSE:
+ return "DO_NOTHING_ON_CLOSE";
+ case WindowConstants.HIDE_ON_CLOSE:
+ return "HIDE_ON_CLOSE";
+ case WindowConstants.DISPOSE_ON_CLOSE:
+ return "DISPOSE_ON_CLOSE";
+ case WindowConstants.EXIT_ON_CLOSE:
+ return "EXIT_ON_CLOSE";
+ default:
+ throw new IllegalArgumentException("Unrecognised code: " + code);
+ }
+ }
}
diff --git a/javax/swing/TransferHandler.java b/javax/swing/TransferHandler.java
index 830feee83..40a36b27d 100644
--- a/javax/swing/TransferHandler.java
+++ b/javax/swing/TransferHandler.java
@@ -1,5 +1,5 @@
/* TransferHandler.java --
- Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,12 +38,14 @@ exception statement from your version. */
package javax.swing;
+import gnu.classpath.NotImplementedException;
+
+import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
-import java.awt.Toolkit;
import java.io.Serializable;
public class TransferHandler implements Serializable
@@ -147,42 +149,48 @@ public class TransferHandler implements Serializable
this.sourceActions = property != null ? COPY : NONE;
}
- public boolean canImport (JComponent c, DataFlavor[] flavors)
+ public boolean canImport(JComponent c, DataFlavor[] flavors)
+ throws NotImplementedException
{
return false;
}
protected Transferable createTransferable(JComponent c)
+ throws NotImplementedException
{
return null;
}
- public void exportAsDrag (JComponent c, InputEvent e, int action)
+ public void exportAsDrag(JComponent c, InputEvent e, int action)
+ throws NotImplementedException
{
// TODO: Implement this properly
}
- protected void exportDone (JComponent c, Transferable data, int action)
+ protected void exportDone(JComponent c, Transferable data, int action)
+ throws NotImplementedException
{
// TODO: Implement this properly
}
public void exportToClipboard(JComponent c, Clipboard clip, int action)
+ throws NotImplementedException
{
// TODO: Implement this properly
}
- public int getSourceActions (JComponent c)
+ public int getSourceActions(JComponent c)
{
return sourceActions;
}
- public Icon getVisualRepresentation (Transferable t)
+ public Icon getVisualRepresentation(Transferable t)
{
return visualRepresentation;
}
- public boolean importData (JComponent c, Transferable t)
+ public boolean importData(JComponent c, Transferable t)
+ throws NotImplementedException
{
return false;
}
diff --git a/javax/swing/UIDefaults.java b/javax/swing/UIDefaults.java
index 00d9700d0..bf5242f65 100644
--- a/javax/swing/UIDefaults.java
+++ b/javax/swing/UIDefaults.java
@@ -96,15 +96,15 @@ public class UIDefaults extends Hashtable
}
public Object createValue(UIDefaults table)
{
- InputMapUIResource im = new InputMapUIResource ();
- for (int i = 0; 2*i+1 < bind.length; ++i)
+ InputMapUIResource im = new InputMapUIResource();
+ for (int i = 0; 2 * i + 1 < bind.length; ++i)
{
- Object curr = bind[2*i];
+ Object curr = bind[2 * i];
if (curr instanceof KeyStroke)
- im.put((KeyStroke) curr, bind[2*i+1]);
+ im.put((KeyStroke) curr, bind[2 * i + 1]);
else
im.put(KeyStroke.getKeyStroke((String) curr),
- bind[2*i+1]);
+ bind[2 * i + 1]);
}
return im;
}
@@ -128,9 +128,9 @@ public class UIDefaults extends Hashtable
public ProxyLazyValue(String s)
{
final String className = s;
- inner = new LazyValue ()
+ inner = new LazyValue()
{
- public Object createValue (UIDefaults table)
+ public Object createValue(UIDefaults table)
{
try
{
@@ -151,16 +151,16 @@ public class UIDefaults extends Hashtable
{
final String className = c;
final String methodName = m;
- inner = new LazyValue ()
+ inner = new LazyValue()
{
- public Object createValue (UIDefaults table)
+ public Object createValue(UIDefaults table)
{
try
{
return Class
- .forName (className)
- .getMethod (methodName, new Class[] {})
- .invoke (null, new Object[] {});
+ .forName(className)
+ .getMethod(methodName, new Class[] {})
+ .invoke(null, new Object[] {});
}
catch (Exception e)
{
@@ -674,7 +674,7 @@ public class UIDefaults extends Hashtable
*/
public Class getUIClass(String id, ClassLoader loader)
{
- String className = (String) get (id);
+ String className = (String) get(id);
if (className == null)
return null;
try
diff --git a/javax/swing/UIManager.java b/javax/swing/UIManager.java
index e1ee28b3f..e6f801163 100644
--- a/javax/swing/UIManager.java
+++ b/javax/swing/UIManager.java
@@ -145,18 +145,19 @@ public class UIManager implements Serializable
static
{
String defaultlaf = System.getProperty("swing.defaultlaf");
- try {
- if (defaultlaf != null)
- {
- Class lafClass = Class.forName(defaultlaf);
- LookAndFeel laf = (LookAndFeel) lafClass.newInstance();
- setLookAndFeel(laf);
- }
- else
- {
- setLookAndFeel(new MetalLookAndFeel());
- }
- }
+ try
+ {
+ if (defaultlaf != null)
+ {
+ Class lafClass = Class.forName(defaultlaf);
+ LookAndFeel laf = (LookAndFeel) lafClass.newInstance();
+ setLookAndFeel(laf);
+ }
+ else
+ {
+ setLookAndFeel(new MetalLookAndFeel());
+ }
+ }
catch (Exception ex)
{
System.err.println("cannot initialize Look and Feel: " + defaultlaf);
@@ -455,7 +456,7 @@ public class UIManager implements Serializable
*/
public static Font getFont(Object key, Locale locale)
{
- return (Font) get(key ,locale);
+ return (Font) get(key, locale);
}
/**
diff --git a/javax/swing/WindowConstants.java b/javax/swing/WindowConstants.java
index aaa0cb9a3..598a61e14 100644
--- a/javax/swing/WindowConstants.java
+++ b/javax/swing/WindowConstants.java
@@ -1,5 +1,5 @@
/* WindowConstants.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,31 +38,42 @@ exception statement from your version. */
package javax.swing;
/**
- * Defines some constants that are used in Swing's top-level
- * containers.
- *
+ * Defines some constants that are used in Swing's top-level containers. See
+ * the following methods:
+ * <ul>
+ * <li>{@link JFrame#setDefaultCloseOperation(int)};</li>
+ * <li>{@link JInternalFrame#setDefaultCloseOperation(int)};</li>
+ * <li>{@link JDialog#setDefaultCloseOperation(int)};</li>
+ * </ul>
+ *
* @author Andrew Selkirk
*/
public interface WindowConstants
{
/**
- * DO_NOTHING_ON_CLOSE
+ * Do nothing when the container is closed.
*/
int DO_NOTHING_ON_CLOSE = 0;
/**
- * HIDE_ON_CLOSE
+ * Hide the container when it is closed.
*/
int HIDE_ON_CLOSE = 1;
/**
- * DISPOSE_ON_CLOSE
+ * Dispose the container when it is closed.
+ *
+ * @see Window#dispose()
*/
int DISPOSE_ON_CLOSE = 2;
/**
- * EXIT_ON_CLOSE
+ * Exit the application when the container is closed.
+ *
+ * @see System#exit(int)
+ *
+ * @since 1.4
*/
- int EXIT_ON_CLOSE =3;
+ int EXIT_ON_CLOSE = 3;
}
diff --git a/javax/swing/border/AbstractBorder.java b/javax/swing/border/AbstractBorder.java
index c995de1c2..16bb238c3 100644
--- a/javax/swing/border/AbstractBorder.java
+++ b/javax/swing/border/AbstractBorder.java
@@ -194,6 +194,6 @@ public abstract class AbstractBorder implements Border, Serializable
height -= borderInsets.top + borderInsets.bottom;
}
- return new Rectangle (x, y, width, height);
+ return new Rectangle(x, y, width, height);
}
}
diff --git a/javax/swing/border/BevelBorder.java b/javax/swing/border/BevelBorder.java
index 403c35c04..5b4761e9e 100644
--- a/javax/swing/border/BevelBorder.java
+++ b/javax/swing/border/BevelBorder.java
@@ -479,7 +479,7 @@ public class BevelBorder extends AbstractBorder
((highlightOuter == null) || (highlightOuter.getAlpha() == 255))
&& ((highlightInner == null) || (highlightInner.getAlpha() == 255))
&& ((shadowInner == null) || (shadowInner.getAlpha() == 255))
- && ((shadowOuter == null) ||(shadowOuter.getAlpha() == 255));
+ && ((shadowOuter == null) || (shadowOuter.getAlpha() == 255));
}
diff --git a/javax/swing/border/CompoundBorder.java b/javax/swing/border/CompoundBorder.java
index a69c5e20a..2ee639cf9 100644
--- a/javax/swing/border/CompoundBorder.java
+++ b/javax/swing/border/CompoundBorder.java
@@ -178,7 +178,7 @@ public class CompoundBorder extends AbstractBorder
Insets borderInsets;
if (insets == null)
- insets = new Insets (0,0,0,0);
+ insets = new Insets(0, 0, 0, 0);
else
insets.left = insets.right = insets.top = insets.bottom = 0;
@@ -217,7 +217,7 @@ public class CompoundBorder extends AbstractBorder
// the implementation from AbstractBorder. However, we want
// to be compatible with the API specification, which overrides
// the getBorderInsets(Component) method.
- return getBorderInsets (c, null);
+ return getBorderInsets(c, null);
}
/**
@@ -239,7 +239,7 @@ public class CompoundBorder extends AbstractBorder
*
* @return The inside border (possibly <code>null</code>).
*/
- public Border getInsideBorder ()
+ public Border getInsideBorder()
{
return insideBorder;
}
diff --git a/javax/swing/border/TitledBorder.java b/javax/swing/border/TitledBorder.java
index 38b575423..56146e01d 100644
--- a/javax/swing/border/TitledBorder.java
+++ b/javax/swing/border/TitledBorder.java
@@ -45,11 +45,10 @@ import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
-import java.awt.Shape;
-import java.awt.font.FontRenderContext;
-import java.awt.font.LineMetrics;
-import java.awt.geom.AffineTransform;
+import java.awt.Point;
+import java.awt.Rectangle;
+import javax.swing.SwingUtilities;
import javax.swing.UIManager;
@@ -464,191 +463,238 @@ public class TitledBorder extends AbstractBorder
public void paintBorder(Component c, Graphics g,
int x, int y, int width, int height)
{
- Measurements mes = getMeasurements(c);
- Font oldFont = g.getFont();
- Color oldColor = g.getColor();
-
- /**
- * A local helper class for painting the border without changing
- * any pixels inside the rectangle of the title text.
- */
- class BorderPainter
- {
- private Component c;
- private Border b;
- private int x, y, width, height;
-
- /**
- * Constructs a BorderPainter.
- *
- * @param c the component whose border is being painted.
- * @param b the border object.
- * @param x the x coordinate of the rectangle delimiting the border.
- * @param y the y coordinate of the rectangle delimiting the border.
- * @param width the width of the rectangle delimiting the border.
- * @param height the width of the rectangle delimiting the border.
- */
- public BorderPainter(Component c, Border b,
- int x, int y, int width, int height)
- {
- this.c = c;
- this.b = b;
- this.x = x;
- this.y = y;
- this.width = width;
- this.height = height;
- }
+ Rectangle borderRect = new Rectangle(x + EDGE_SPACING, y + EDGE_SPACING,
+ width - (EDGE_SPACING * 2),
+ height - (EDGE_SPACING * 2));
+ Point textLoc = new Point();
+
+ // Save color and font.
+ Color savedColor = g.getColor();
+ Font savedFont = g.getFont();
+
+ // The font metrics.
+ Font font = getFont(c);
+ g.setFont(font);
+ FontMetrics fm = c.getFontMetrics(font);
+
+ layoutBorderWithTitle(c, fm, borderRect, textLoc);
+ paintBorderWithTitle(c, g, x, y, width, height, borderRect, textLoc, fm);
+
+ g.setColor(getTitleColor());
+ g.drawString(getTitle(), textLoc.x, textLoc.y);
+ g.setFont(savedFont);
+ g.setColor(savedColor);
+ }
+ /**
+ * Calculates the bounding box of the inner border and the location of the
+ * title string.
+ *
+ * @param c the component on which to paint the border
+ * @param fm the font metrics
+ * @param borderRect output parameter, holds the bounding box of the inner
+ * border on method exit
+ * @param textLoc output parameter, holds the location of the title text
+ * on method exit
+ */
+ private void layoutBorderWithTitle(Component c, FontMetrics fm,
+ Rectangle borderRect,
+ Point textLoc)
+ {
+ Border b = getBorder();
+
+ // The font metrics.
+ int fontHeight = fm.getHeight();
+ int fontDescent = fm.getDescent();
+ int fontAscent = fm.getAscent();
+ int titleWidth = fm.stringWidth(getTitle());
+
+ // The base insets.
+ Insets insets;
+ if (b == null)
+ insets = new Insets(0, 0, 0, 0);
+ else
+ insets = b.getBorderInsets(c);
- /**
- * Paints the entire border.
- */
- public void paint(Graphics g)
- {
- if (b != null)
- b.paintBorder(c, g, x, y, width, height);
- }
+ // The offset of the border rectangle, dependend on the title placement.
+ int offset;
+ // Layout border and text vertically.
+ int titlePosition = getTitlePosition();
+ switch (titlePosition)
+ {
+ case ABOVE_BOTTOM:
+ textLoc.y = borderRect.y + borderRect.height - insets.bottom
+ - fontDescent - TEXT_SPACING;
+ break;
+ case BOTTOM:
+ borderRect.height -= fontHeight / 2;
+ textLoc.y = borderRect.y + borderRect.height - fontDescent
+ + (fontAscent + fontDescent - insets.bottom) / 2;
+ break;
+ case BELOW_BOTTOM:
+ borderRect.height -= fontHeight;
+ textLoc.y = borderRect.y + borderRect.height + fontAscent
+ + TEXT_SPACING;
+ break;
+ case ABOVE_TOP:
+ offset = fontAscent + fontDescent
+ + Math.max(EDGE_SPACING, TEXT_SPACING * 2) - EDGE_SPACING;
+ borderRect.y += offset;
+ borderRect.height -= offset;
+ textLoc.y = borderRect.y - (fontDescent + TEXT_SPACING);
+ break;
+ case BELOW_TOP:
+ textLoc.y = borderRect.y + insets.top + fontAscent + TEXT_SPACING;
+ break;
+ case TOP:
+ case DEFAULT_POSITION:
+ default:
+ offset = Math.max(0, ((fontAscent / 2) + TEXT_SPACING) - EDGE_SPACING);
+ borderRect.y += offset;
+ borderRect.height -= offset;
+ textLoc.y = borderRect.y - fontDescent
+ + (insets.top + fontAscent + fontDescent) / 2;
+ break;
+ }
- /**
- * Paints the border, clipping the drawing operation to a
- * given rectangular area.
- */
- private void paint(Graphics g,
- int clipX, int clipY, int clipWidth, int clipHeight)
+ // Layout border and text horizontally.
+ int justification = getTitleJustification();
+ // Adjust justification for LEADING and TRAILING depending on the direction
+ // of the component.
+ if (c.getComponentOrientation().isLeftToRight())
{
- Shape oldClip = g.getClip();
- try
- {
- g.clipRect(clipX, clipY, clipWidth, clipHeight);
- paint(g);
- }
- finally
- {
- g.setClip(oldClip);
- }
+ if (justification == LEADING || justification == DEFAULT_JUSTIFICATION)
+ justification = LEFT;
+ else if (justification == TRAILING)
+ justification = RIGHT;
}
-
-
- /**
- * Paints the border without affecting a given rectangular area.
- * This is used for painting the border without drawing anything
- * underneath the title text.
- *
- * <p>Since we do not want to introduce unnecessary dependencies
- * on Java 2D, we perform the clipping without constructive geometry
- * (provided by java.awt.geom.Area). Instead, the border&#x2019;s
- * bounding rectangle is split into smaller parts, which are then
- * clipped and painted individually.:
- *
- * <p><pre>
- * +--------------------+ +--------------------+
- * | | | 1 |
- * | +--------+ | +---+--------+-------+
- * | | hole | | |====> | 2 | hole | 3 |
- * | +--------+ | |---+--------+-------+
- * | | | 4 |
- * +--------------------+ +--------------------+</pre>
- *
- */
- public void paintExcept(Graphics g,
- int holeX, int holeY, int holeWidth, int holeHeight)
+ else
{
- int stripeHeight;
-
- stripeHeight = holeY - y;
- if (stripeHeight > 0)
- paint(g, x, y, width, stripeHeight); // patch #1 in the image above
-
- stripeHeight = holeHeight;
- if (stripeHeight > 0)
- {
- paint(g, x, holeY, holeX - x, stripeHeight); // patches #2 and #3
- paint(g, holeX + holeWidth, holeY, x + width - (holeX + holeWidth), stripeHeight);
- }
-
- stripeHeight = height - (holeY - y + holeHeight);
- if (stripeHeight > 0)
- paint(g, x, y + height - stripeHeight, width, stripeHeight); // #4
+ if (justification == LEADING || justification == DEFAULT_JUSTIFICATION)
+ justification = RIGHT;
+ else if (justification == TRAILING)
+ justification = LEFT;
}
- };
-
- BorderPainter bp;
- int textX, textY, borderWidth, borderHeight;
-
- borderWidth = width - (mes.outerSpacing.left + mes.outerSpacing.right);
- borderHeight = height - (mes.outerSpacing.top + mes.outerSpacing.bottom);
- bp = new BorderPainter(c, getBorder(),
- x + mes.outerSpacing.left, y + mes.outerSpacing.top,
- borderWidth, borderHeight);
- switch (getRealTitleJustification(c))
+ switch (justification)
{
- case LEFT:
- textX = x + EDGE_SPACING + TEXT_INSET_H;
- break;
-
- case CENTER:
- textX = x + (borderWidth - mes.textWidth) / 2;
- break;
-
- case RIGHT:
- textX = x + borderWidth - (mes.textWidth + TEXT_INSET_H);
- break;
-
- default:
- throw new IllegalStateException();
+ case CENTER:
+ textLoc.x = borderRect.x + (borderRect.width - titleWidth) / 2;
+ break;
+ case RIGHT:
+ textLoc.x = borderRect.x + borderRect.width - titleWidth
+ - TEXT_INSET_H - insets.right;
+ break;
+ case LEFT:
+ default:
+ textLoc.x = borderRect.x + TEXT_INSET_H + insets.left;
}
+ }
- switch (titlePosition)
- {
- case ABOVE_TOP:
- textY = y + EDGE_SPACING;
- break;
-
- case TOP:
- case DEFAULT_POSITION:
- default:
- textY = y + mes.outerSpacing.top + mes.borderInsets.top - mes.textAscent
- + mes.lineHeight;
- break;
-
- case BELOW_TOP:
- textY = y + mes.outerSpacing.top + mes.borderInsets.top + TEXT_SPACING;
- break;
-
- case ABOVE_BOTTOM:
- textY = y + height - mes.outerSpacing.bottom - mes.borderInsets.bottom
- - TEXT_SPACING - (mes.textAscent + mes.textDescent);
- break;
-
- case BOTTOM:
- case BELOW_BOTTOM:
- textY = y + height - (mes.textAscent + mes.textDescent);
- break;
- }
+ /**
+ * Paints the border with the title.
+ *
+ * @param c the component to paint on
+ * @param g the graphics context used for paintin
+ * @param x the upper left corner of the whole border
+ * @param y the upper left corner of the whole border
+ * @param width the width of the whole border
+ * @param height the width of the whole border
+ * @param borderRect the bounding box of the inner border
+ * @param textLoc the location of the border title
+ * @param fm the font metrics of the title
+ */
+ private void paintBorderWithTitle(Component c, Graphics g, int x, int y,
+ int width, int height,
+ Rectangle borderRect, Point textLoc,
+ FontMetrics fm)
+ {
+ Border b = getBorder();
+ int fontDescent = fm.getDescent();
+ int fontAscent = fm.getAscent();
+ int titleWidth = fm.stringWidth(getTitle());
- if (mes.trimmedText == null)
- bp.paint(g);
- else
- {
- try
+ if (b != null)
{
- g.setFont(mes.font);
- g.setColor(getTitleColor());
- g.drawString(mes.trimmedText, textX, textY + mes.textAscent);
+ // Paint border in segments, when the title is painted above the
+ // border.
+ if (((titlePosition == TOP || titlePosition == DEFAULT_POSITION)
+ && (borderRect.y > textLoc.y - fontAscent))
+ || (titlePosition == BOTTOM
+ && borderRect.y + borderRect.height < textLoc.y + fontDescent))
+ {
+ Rectangle clip = new Rectangle();
+ Rectangle saved = g.getClipBounds();
+
+ // Paint border left from the text.
+ clip.setBounds(saved);
+ SwingUtilities.computeIntersection(x, y, textLoc.x - x - 1,
+ height, clip);
+ if (! clip.isEmpty())
+ {
+ g.setClip(clip);
+ b.paintBorder(c, g, borderRect.x, borderRect.y,
+ borderRect.width,
+ borderRect.height);
+ }
+ // Paint border right from the text.
+ clip.setBounds(saved);
+ SwingUtilities.computeIntersection(textLoc.x + titleWidth + 1, y,
+ x + width - (textLoc.x + titleWidth + 1), height, clip);
+ if (! clip.isEmpty())
+ {
+ g.setClip(clip);
+ b.paintBorder(c, g, borderRect.x, borderRect.y,
+ borderRect.width,
+ borderRect.height);
+ }
+
+ if (titlePosition == TOP || titlePosition == DEFAULT_POSITION)
+ {
+ // Paint border below the text.
+ clip.setBounds(saved);
+ SwingUtilities.computeIntersection(textLoc.x - 1,
+ textLoc.y + fontDescent,
+ titleWidth + 2,
+ y + height - textLoc.y - fontDescent,
+ clip);
+ if (! clip.isEmpty())
+ {
+ g.setClip(clip);
+ b.paintBorder(c, g, borderRect.x, borderRect.y,
+ borderRect.width,
+ borderRect.height);
+ }
+
+ }
+ else
+ {
+ // Paint border above the text.
+ clip.setBounds(saved);
+ SwingUtilities.computeIntersection(textLoc.x - 1, y,
+ titleWidth + 2,
+ textLoc.y - fontDescent - y,
+ clip);
+ if (! clip.isEmpty())
+ {
+ g.setClip(clip);
+ b.paintBorder(c, g, borderRect.x, borderRect.y,
+ borderRect.width,
+ borderRect.height);
+ }
+
+ }
+ g.setClip(saved);
+ }
+ else
+ {
+ b.paintBorder(c, g, borderRect.x, borderRect.y, borderRect.width,
+ borderRect.height);
+ }
}
- finally
- {
- g.setFont(oldFont);
- g.setColor(oldColor);
- }
- bp.paintExcept(g, textX, textY,
- mes.textWidth, mes.textAscent + mes.textDescent);
- }
}
-
-
+
/**
* Measures the width of this border.
*
@@ -682,7 +728,72 @@ public class TitledBorder extends AbstractBorder
*/
public Insets getBorderInsets(Component c, Insets insets)
{
- return getMeasurements(c).getContentInsets(insets);
+ // Initialize insets with the insets from our border.
+ Border border = getBorder();
+ if (border != null)
+ {
+ if (border instanceof AbstractBorder)
+ {
+ AbstractBorder aBorder = (AbstractBorder) border;
+ aBorder.getBorderInsets(c, insets);
+ }
+ else
+ {
+ Insets i = border.getBorderInsets(c);
+ insets.top = i.top;
+ insets.bottom = i.bottom;
+ insets.left = i.left;
+ insets.right = i.right;
+ }
+ }
+ else
+ {
+ insets.top = 0;
+ insets.bottom = 0;
+ insets.left = 0;
+ insets.right = 0;
+ }
+
+ // Add spacing.
+ insets.top += EDGE_SPACING + TEXT_SPACING;
+ insets.bottom += EDGE_SPACING + TEXT_SPACING;
+ insets.left += EDGE_SPACING + TEXT_SPACING;
+ insets.right += EDGE_SPACING + TEXT_SPACING;
+
+ String title = getTitle();
+ if (c != null && title != null && !title.equals(""))
+ {
+ Font font = getFont(c);
+ FontMetrics fm = c.getFontMetrics(font);
+ int ascent = fm.getAscent();
+ int descent = fm.getDescent();
+ int height = fm.getHeight();
+ switch (getTitlePosition())
+ {
+ case ABOVE_BOTTOM:
+ insets.bottom += ascent + descent + TEXT_SPACING;
+ break;
+ case BOTTOM:
+ insets.bottom += ascent + descent;
+ break;
+ case BELOW_BOTTOM:
+ insets.bottom += height;
+ break;
+ case ABOVE_TOP:
+ insets.top += ascent + descent +
+ Math.max(EDGE_SPACING, TEXT_SPACING * 2)
+ - EDGE_SPACING;
+ break;
+ case BELOW_TOP:
+ insets.top += ascent + descent + TEXT_SPACING;
+ break;
+ case TOP:
+ case DEFAULT_POSITION:
+ default:
+ insets.top += ascent + descent;
+ }
+ }
+ return insets;
}
@@ -919,7 +1030,26 @@ public class TitledBorder extends AbstractBorder
*/
public Dimension getMinimumSize(Component c)
{
- return getMeasurements(c).getMinimumSize();
+ Insets i = getBorderInsets(c);
+ Dimension minSize = new Dimension(i.left + i.right, i.top + i.bottom);
+ Font font = getFont(c);
+ FontMetrics fm = c.getFontMetrics(font);
+ int titleWidth = fm.stringWidth(getTitle());
+ switch (getTitlePosition())
+ {
+ case ABOVE_TOP:
+ case BELOW_BOTTOM:
+ minSize.width = Math.max(minSize.width, titleWidth);
+ break;
+ case BELOW_TOP:
+ case ABOVE_BOTTOM:
+ case TOP:
+ case BOTTOM:
+ case DEFAULT_POSITION:
+ default:
+ minSize.width += titleWidth;
+ }
+ return minSize;
}
@@ -943,253 +1073,4 @@ public class TitledBorder extends AbstractBorder
return new Font("Dialog", Font.PLAIN, 12);
}
-
- /**
- * Returns the horizontal alignment of the title text in relation to
- * the border, mapping the component-dependent alignment constants
- * {@link #LEADING}, {@link #TRAILING} and {@link #DEFAULT_JUSTIFICATION}
- * to the correct value according to the embedded component&#x2019;s
- * orientation.
- *
- * @param c the Component for which this TitledBorder is the border.
- *
- * @return one of the values {@link #LEFT}, {@link #CENTER}, or {@link
- * #RIGHT}.
- */
- private int getRealTitleJustification(Component c)
- {
- switch (titleJustification)
- {
- case DEFAULT_JUSTIFICATION:
- case LEADING:
- if ((c == null) || c.getComponentOrientation().isLeftToRight())
- return LEFT;
- else
- return RIGHT;
-
- case TRAILING:
- if ((c == null) || c.getComponentOrientation().isLeftToRight())
- return RIGHT;
- else
- return LEFT;
-
- default:
- return titleJustification;
- }
- }
-
-
- /**
- * Performs various measurements for the current state of this TitledBorder
- * and the given Component.
- *
- * @param c the component (<code>null</code> not permitted).
- *
- * @return Various measurements.
- */
- private Measurements getMeasurements(Component c)
- {
- Measurements m = new Measurements();
- FontMetrics fmet;
-
- m.font = getFont(c);
- fmet = c.getFontMetrics(m.font);
- m.border = getBorder();
- if (m.border != null)
- m.borderInsets = m.border.getBorderInsets(c);
- else
- m.borderInsets = new Insets(0, 0, 0, 0);
-
- if (title != null)
- {
- m.trimmedText = title.trim();
- if (m.trimmedText.length() == 0)
- m.trimmedText = null;
- }
-
- if (m.trimmedText != null)
- {
- m.textAscent = fmet.getAscent();
- m.textDescent = fmet.getDescent() + fmet.getLeading();
-
- FontRenderContext frc = new FontRenderContext(new AffineTransform(),
- false, false);
- LineMetrics lmet = m.font.getLineMetrics(m.trimmedText, 0,
- m.trimmedText.length(), frc);
- m.lineHeight = (int) lmet.getStrikethroughOffset();
-
- // Fallback in case that LineMetrics is not available/working.
- if (m.lineHeight == 0)
- m.lineHeight = (int) (0.3333 * (double) m.textAscent);
- m.textWidth = fmet.stringWidth(m.trimmedText) + 3;
- }
- else
- {
- m.textAscent = 0;
- m.textDescent = 0;
- }
-
- m.innerSpacing = new Insets(EDGE_SPACING, EDGE_SPACING, EDGE_SPACING,
- EDGE_SPACING);
- m.outerSpacing = new Insets(EDGE_SPACING, EDGE_SPACING, EDGE_SPACING,
- EDGE_SPACING);
-
- switch (titlePosition)
- {
- case ABOVE_TOP:
- m.outerSpacing.top += m.textAscent + m.textDescent + TEXT_SPACING;
- break;
-
- case TOP:
- m.outerSpacing.top += m.textDescent + m.lineHeight;
- m.innerSpacing.top += m.textAscent - m.lineHeight;
- break;
-
- case BELOW_TOP:
- m.innerSpacing.top += m.textAscent + m.textDescent + TEXT_SPACING;
- break;
-
- case ABOVE_BOTTOM:
- m.innerSpacing.bottom += m.textAscent + m.textDescent + TEXT_SPACING;
- break;
-
- case BOTTOM:
- m.innerSpacing.bottom += Math.max(m.textAscent - m.lineHeight, 0);
- m.outerSpacing.bottom += m.textDescent + m.lineHeight;
- break;
-
- case BELOW_BOTTOM:
- m.outerSpacing.bottom += m.textAscent + m.textDescent;
- break;
-
- default:
- m.outerSpacing.top += m.textAscent;
- }
-
- return m;
- }
-
-
- /**
- * A private helper class for holding the result of measuring the
- * distances of a TitledBorder. While it would be possible to cache
- * these objects, it does not seem to be worth the effort. Note that
- * invalidating the cache would be tricky, especially since there is
- * no notification mechanism that would inform the cache when
- * border has changed, so it would return different insets.
- */
- private static class Measurements
- {
- /**
- * The font used for displaying the title text. Note that it can
- * well be that the TitledBorder&#x2019;s font is <code>null</code>,
- * which means that the font is to be retrieved from the current
- * LookAndFeel. In this case, this <code>font</code> field will
- * contain the result of the retrieval. Therefore, it is safe
- * to assume that this <code>font</code> field will never have
- * a <code>null</code> value.
- */
- Font font;
-
-
- /**
- * The number of pixels between the base line and the top of the
- * text box.
- */
- int textAscent;
-
-
- /**
- * The number of pixels between the base line and the bottom of
- * the text box.
- */
- int textDescent;
-
- /**
- * The number of pixels between the base line and the height where
- * a strike-through would be drawn.
- */
- int lineHeight;
-
- /**
- * The title text after removing leading and trailing white space
- * characters. If the title consists only of white space, the
- * value of <code>trimmedText</code> will be <code>null</code>.
- */
- String trimmedText;
-
-
- /**
- * The width of the trimmed title text in pixels.
- */
- int textWidth;
-
-
- /**
- * The border that constitutes the interior border
- * underneath the title text.
- */
- Border border;
-
-
- /**
- * The distance between the TitledBorder and the interior border.
- */
- Insets outerSpacing;
-
- /**
- * The width of the interior border, as returned by
- * <code>border.getBorderInsets()</code>.
- */
- Insets borderInsets;
-
-
- /**
- * The distance between the interior border and the nested
- * Component for which this TitledBorder is a border.
- */
- Insets innerSpacing;
-
-
- /**
- * Determines the insets of the nested component when it has a
- * TitledBorder as its border. Used by {@link
- * TitledBorder#getBorderInsets(Component, Insets)}.
- *
- * @param i an Insets object for storing the results into, or
- * <code>null</code> to cause the creation of a
- * new instance.
- *
- * @return the <code>i</code> object, or a new Insets object
- * if <code>null</code> was passed for <code>i</code>.
- */
- public Insets getContentInsets(Insets i)
- {
- if (i == null)
- i = new Insets(0, 0, 0, 0);
- i.left = outerSpacing.left + borderInsets.left + innerSpacing.left;
- i.right = outerSpacing.right + borderInsets.right + innerSpacing.right;
- i.top = outerSpacing.top + borderInsets.top + innerSpacing.top;
- i.bottom = outerSpacing.bottom + borderInsets.bottom + innerSpacing.bottom;
- return i;
- }
-
-
- /**
- * Calculates the minimum size needed for displaying the border
- * and its title. Used by {@link TitledBorder#getMinimumSize(Component)}.
- *
- * @return The minimum size.
- */
- public Dimension getMinimumSize()
- {
- int width;
- Insets insets;
-
- insets = getContentInsets(null);
- width = Math.max(insets.left + insets.right, textWidth + 2
- * TEXT_INSET_H);
- return new Dimension(width, insets.top + insets.bottom);
- }
- }
}
diff --git a/javax/swing/event/EventListenerList.java b/javax/swing/event/EventListenerList.java
index a7fbec44d..6a2f34ebb 100644
--- a/javax/swing/event/EventListenerList.java
+++ b/javax/swing/event/EventListenerList.java
@@ -1,5 +1,5 @@
/* EventListenerList.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -187,11 +187,15 @@ public class EventListenerList
/**
- * Get a list of listenerType/listener pairs
- * @return Listener list
+ * Returns an array containing a sequence of listenerType/listener pairs, one
+ * for each listener.
+ *
+ * @return An array containing the listener types and references.
*/
public Object[] getListenerList()
{
+ // returning the internal storage is a bad idea, but tests show that the
+ // reference implementation does this...
return listenerList;
}
diff --git a/javax/swing/plaf/basic/BasicButtonUI.java b/javax/swing/plaf/basic/BasicButtonUI.java
index 7dbcb9146..0a537c4bd 100644
--- a/javax/swing/plaf/basic/BasicButtonUI.java
+++ b/javax/swing/plaf/basic/BasicButtonUI.java
@@ -72,7 +72,7 @@ public class BasicButtonUI extends ButtonUI
* A constant added to the defaultTextIconGap to adjust the text
* within this particular button.
*/
- protected int defaultTextShiftOffset = 0;
+ protected int defaultTextShiftOffset;
private int textShiftOffset;
@@ -268,10 +268,9 @@ public class BasicButtonUI extends ButtonUI
*/
public Dimension getPreferredSize(JComponent c)
{
- AbstractButton b = (AbstractButton)c;
- Dimension d =
- BasicGraphicsUtils.getPreferredButtonSize
- (b, defaultTextIconGap + defaultTextShiftOffset);
+ AbstractButton b = (AbstractButton) c;
+ Dimension d = BasicGraphicsUtils.getPreferredButtonSize(b,
+ defaultTextIconGap + defaultTextShiftOffset);
return d;
}
diff --git a/javax/swing/plaf/basic/BasicCheckBoxUI.java b/javax/swing/plaf/basic/BasicCheckBoxUI.java
index 14dadb85c..1010139b8 100644
--- a/javax/swing/plaf/basic/BasicCheckBoxUI.java
+++ b/javax/swing/plaf/basic/BasicCheckBoxUI.java
@@ -1,5 +1,5 @@
/* BasicCheckBoxUI.java
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,25 +38,32 @@ exception statement from your version. */
package javax.swing.plaf.basic;
-import javax.swing.Icon;
+import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
+/**
+ * A UI delegate for the {@link JCheckBox} component.
+ */
public class BasicCheckBoxUI extends BasicRadioButtonUI
{
- public static ComponentUI createUI(final JComponent c) {
+ /**
+ * Returns a UI delegate (that is, an instance of this class) for the
+ * specified component.
+ *
+ * @param c the component (this should be a {@link JCheckBox}).
+ *
+ * @return A new instance of <code>BasicCheckBoxUI</code>.
+ */
+ public static ComponentUI createUI(JComponent c) {
return new BasicCheckBoxUI();
}
- public Icon getDefaultIcon()
- {
- return UIManager.getIcon("CheckBox.icon");
- }
-
/**
- * Returns the prefix for entries in the {@link UIManager} defaults table.
+ * Returns the prefix for entries in the {@link UIManager} defaults table
+ * (<code>"CheckBox."</code> in this case).
*
* @return "CheckBox."
*/
diff --git a/javax/swing/plaf/basic/BasicComboBoxUI.java b/javax/swing/plaf/basic/BasicComboBoxUI.java
index 557eea93f..ea6f98504 100644
--- a/javax/swing/plaf/basic/BasicComboBoxUI.java
+++ b/javax/swing/plaf/basic/BasicComboBoxUI.java
@@ -1,5 +1,5 @@
/* BasicComboBoxUI.java --
- Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -66,12 +66,14 @@ import javax.swing.CellRendererPane;
import javax.swing.ComboBoxEditor;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultListCellRenderer;
+import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
import javax.swing.LookAndFeel;
+import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
@@ -546,7 +548,7 @@ public class BasicComboBoxUI extends ComboBoxUI
}
/**
- * Unconfigures the editor for this combo nox. This method is not implemented.
+ * Unconfigures the editor for this combo box.
*/
protected void unconfigureEditor()
{
@@ -711,12 +713,14 @@ public class BasicComboBoxUI extends ComboBoxUI
}
public int getAccessibleChildrenCount(JComponent c)
+ throws NotImplementedException
{
// FIXME: Need to implement
return 0;
}
public Accessible getAccessibleChild(JComponent c, int i)
+ throws NotImplementedException
{
// FIXME: Need to implement
return null;
@@ -731,7 +735,9 @@ public class BasicComboBoxUI extends ComboBoxUI
* @return true if the specified key is a navigation key and false otherwis
*/
protected boolean isNavigationKey(int keyCode)
+ throws NotImplementedException
{
+ // FIXME: Need to implement
return false;
}
@@ -780,9 +786,7 @@ public class BasicComboBoxUI extends ComboBoxUI
Insets i = comboBox.getInsets();
int arrowSize = h - (i.top + i.bottom);
if (arrowButton != null)
- {
- arrowSize = arrowButton.getWidth();
- }
+ arrowSize = arrowButton.getWidth();
return new Rectangle(i.left, i.top, w - (i.left + i.right + arrowSize),
h - (i.top + i.left));
}
@@ -822,14 +826,12 @@ public class BasicComboBoxUI extends ComboBoxUI
if (hasFocus && ! isPopupVisible(comboBox))
{
comp = renderer.getListCellRendererComponent(listBox,
- comboBox.getSelectedItem(),
- -1, true, false);
+ comboBox.getSelectedItem(), -1, true, false);
}
else
{
comp = renderer.getListCellRendererComponent(listBox,
- comboBox.getSelectedItem(),
- -1, false, false);
+ comboBox.getSelectedItem(), -1, false, false);
Color bg = UIManager.getColor("ComboBox.disabledForeground");
comp.setBackground(bg);
}
@@ -871,13 +873,9 @@ public class BasicComboBoxUI extends ComboBoxUI
{
Color saved = g.getColor();
if (comboBox.isEnabled())
- {
- g.setColor(UIManager.getColor("UIManager.background"));
- }
+ g.setColor(UIManager.getColor("UIManager.background"));
else
- {
- g.setColor(UIManager.getColor("UIManager.disabledBackground"));
- }
+ g.setColor(UIManager.getColor("UIManager.disabledBackground"));
g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
g.setColor(saved);
}
@@ -897,9 +895,7 @@ public class BasicComboBoxUI extends ComboBoxUI
protected Dimension getDefaultSize()
{
Component comp = DEFAULT_RENDERER.getListCellRendererComponent(listBox,
- " ", -1,
- false,
- false);
+ " ", -1, false, false);
currentValuePane.add(comp);
comp.setFont(comboBox.getFont());
Dimension d = comp.getPreferredSize();
@@ -974,19 +970,22 @@ public class BasicComboBoxUI extends ComboBoxUI
* by the look and feel.
*/
protected void installKeyboardActions()
- throws NotImplementedException
{
- // FIXME: Need to implement.
+ SwingUtilities.replaceUIInputMap(comboBox,
+ JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
+ (InputMap) UIManager.get("ComboBox.ancestorInputMap"));
+ // Install any action maps here.
}
-
+
/**
* Uninstalls the keyboard actions for the {@link JComboBox} there were
* installed by in {@link #installListeners}.
*/
protected void uninstallKeyboardActions()
- throws NotImplementedException
{
- // FIXME: Need to implement.
+ SwingUtilities.replaceUIInputMap(comboBox,
+ JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null);
+ // Uninstall any action maps here.
}
/**
@@ -1145,9 +1144,7 @@ public class BasicComboBoxUI extends ComboBoxUI
ComboBoxModel model = comboBox.getModel();
Object v = model.getSelectedItem();
if (editor != null)
- {
- comboBox.configureEditor(comboBox.getEditor(), v);
- }
+ comboBox.configureEditor(comboBox.getEditor(), v);
comboBox.repaint();
}
}
@@ -1166,9 +1163,10 @@ public class BasicComboBoxUI extends ComboBoxUI
* Invoked whenever key is pressed while JComboBox is in focus.
*/
public void keyPressed(KeyEvent e)
+ throws NotImplementedException
{
- // FIXME: This method calls JComboBox.selectWithKeyChar if the key that was
- // pressed is not a navigation key.
+ // FIXME: This method calls JComboBox.selectWithKeyChar if the key that
+ // was pressed is not a navigation key.
}
}
@@ -1198,10 +1196,8 @@ public class BasicComboBoxUI extends ComboBoxUI
comboBox.revalidate();
}
if (editor != null)
- {
- comboBox.configureEditor(comboBox.getEditor(),
- comboBox.getSelectedItem());
- }
+ comboBox.configureEditor(comboBox.getEditor(),
+ comboBox.getSelectedItem());
comboBox.repaint();
}
@@ -1215,9 +1211,7 @@ public class BasicComboBoxUI extends ComboBoxUI
int start = e.getIndex0();
int end = e.getIndex1();
if (start == 0 && comboBox.getItemCount() - (end - start + 1) == 0)
- {
- contentsChanged(e);
- }
+ contentsChanged(e);
else if (start != -1 || end != -1)
{
ListCellRenderer renderer = comboBox.getRenderer();
@@ -1227,10 +1221,8 @@ public class BasicComboBoxUI extends ComboBoxUI
// TODO: Optimize using prototype here.
for (int i = start; i <= end; ++i)
{
- Component comp =
- renderer.getListCellRendererComponent(listBox,
- model.getElementAt(i),
- -1, false, false);
+ Component comp = renderer.getListCellRendererComponent(listBox,
+ model.getElementAt(i), -1, false, false);
currentValuePane.add(comp);
comp.setFont(comboBox.getFont());
Dimension dim = comp.getPreferredSize();
@@ -1241,13 +1233,9 @@ public class BasicComboBoxUI extends ComboBoxUI
if (displaySize.width < w || displaySize.height < h)
{
if (displaySize.width < w)
- {
- displaySize.width = w;
- }
+ displaySize.width = w;
if (displaySize.height < h)
- {
- displaySize.height = h;
- }
+ displaySize.height = h;
comboBox.revalidate();
if (editor != null)
{
@@ -1297,37 +1285,37 @@ public class BasicComboBoxUI extends ComboBoxUI
if (e.getPropertyName().equals("enabled"))
{
- arrowButton.setEnabled(comboBox.isEnabled());
+ arrowButton.setEnabled(comboBox.isEnabled());
- if (comboBox.isEditable())
- comboBox.getEditor().getEditorComponent().setEnabled(comboBox
- .isEnabled());
+ if (comboBox.isEditable())
+ comboBox.getEditor().getEditorComponent().setEnabled(
+ comboBox.isEnabled());
}
else if (e.getPropertyName().equals("editable"))
{
- if (comboBox.isEditable())
- {
- configureEditor();
- addEditor();
- }
- else
- {
- unconfigureEditor();
- removeEditor();
- }
-
- comboBox.revalidate();
- comboBox.repaint();
+ if (comboBox.isEditable())
+ {
+ configureEditor();
+ addEditor();
+ }
+ else
+ {
+ unconfigureEditor();
+ removeEditor();
+ }
+
+ comboBox.revalidate();
+ comboBox.repaint();
}
else if (e.getPropertyName().equals("dataModel"))
{
- // remove ListDataListener from old model and add it to new model
- ComboBoxModel oldModel = (ComboBoxModel) e.getOldValue();
- if (oldModel != null)
- oldModel.removeListDataListener(listDataListener);
+ // remove ListDataListener from old model and add it to new model
+ ComboBoxModel oldModel = (ComboBoxModel) e.getOldValue();
+ if (oldModel != null)
+ oldModel.removeListDataListener(listDataListener);
- if ((ComboBoxModel) e.getNewValue() != null)
- comboBox.getModel().addListDataListener(listDataListener);
+ if ((ComboBoxModel) e.getNewValue() != null)
+ comboBox.getModel().addListDataListener(listDataListener);
}
else if (e.getPropertyName().equals("font"))
{
@@ -1339,7 +1327,7 @@ public class BasicComboBoxUI extends ComboBoxUI
comboBox.repaint();
}
- // FIXME: Need to handle changes in other bound properties.
+ // FIXME: Need to handle changes in other bound properties.
}
}
diff --git a/javax/swing/plaf/basic/BasicComboPopup.java b/javax/swing/plaf/basic/BasicComboPopup.java
index d4eabc602..0d822955b 100644
--- a/javax/swing/plaf/basic/BasicComboPopup.java
+++ b/javax/swing/plaf/basic/BasicComboPopup.java
@@ -38,8 +38,6 @@ exception statement from your version. */
package javax.swing.plaf.basic;
-import gnu.classpath.NotImplementedException;
-
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
@@ -294,9 +292,8 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup
* This method uninstalls keyboard actions installed by the UI.
*/
protected void uninstallKeyboardActions()
- throws NotImplementedException
{
- // FIXME: Need to implement
+ // Nothing to do here.
}
/**
@@ -559,12 +556,11 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup
}
/**
- * DOCUMENT ME!
+ * Installs the keyboard actions.
*/
protected void installKeyboardActions()
- throws NotImplementedException
{
- // FIXME: Need to implement
+ // Nothing to do here
}
/**
diff --git a/javax/swing/plaf/basic/BasicDirectoryModel.java b/javax/swing/plaf/basic/BasicDirectoryModel.java
index a694f3280..ef7a880c2 100644
--- a/javax/swing/plaf/basic/BasicDirectoryModel.java
+++ b/javax/swing/plaf/basic/BasicDirectoryModel.java
@@ -227,16 +227,16 @@ public class BasicDirectoryModel extends AbstractListModel
if (aTrav == bTrav)
{
- String aname = a.getName().toLowerCase();
- String bname = b.getName().toLowerCase();
- return ((aname.compareTo(bname) < 0) ? true : false);
+ String aname = a.getName().toLowerCase();
+ String bname = b.getName().toLowerCase();
+ return (aname.compareTo(bname) < 0) ? true : false;
}
else
{
- if (aTrav)
- return true;
- else
- return false;
+ if (aTrav)
+ return true;
+ else
+ return false;
}
}
diff --git a/javax/swing/plaf/basic/BasicFileChooserUI.java b/javax/swing/plaf/basic/BasicFileChooserUI.java
index daa977083..9adb0c642 100644
--- a/javax/swing/plaf/basic/BasicFileChooserUI.java
+++ b/javax/swing/plaf/basic/BasicFileChooserUI.java
@@ -365,10 +365,10 @@ public class BasicFileChooserUI extends FileChooserUI
{
/** DOCUMENT ME! */
- private Object lastSelected = null;
+ private Object lastSelected;
/** DOCUMENT ME! */
- private JList list = null;
+ private JList list;
/**
* Creates a new DoubleClickListener object.
diff --git a/javax/swing/plaf/basic/BasicIconFactory.java b/javax/swing/plaf/basic/BasicIconFactory.java
index 6debd6495..cad0d0e8a 100644
--- a/javax/swing/plaf/basic/BasicIconFactory.java
+++ b/javax/swing/plaf/basic/BasicIconFactory.java
@@ -56,8 +56,14 @@ public class BasicIconFactory implements Serializable
private static class DummyIcon
implements Icon
{
- public int getIconHeight() { return 10; }
- public int getIconWidth() { return 10; }
+ public int getIconHeight()
+ {
+ return 10;
+ }
+ public int getIconWidth()
+ {
+ return 10;
+ }
public void paintIcon(Component c, Graphics g, int x, int y)
{
Color save = g.getColor();
diff --git a/javax/swing/plaf/basic/BasicInternalFrameUI.java b/javax/swing/plaf/basic/BasicInternalFrameUI.java
index 0a330e776..a5f87653f 100644
--- a/javax/swing/plaf/basic/BasicInternalFrameUI.java
+++ b/javax/swing/plaf/basic/BasicInternalFrameUI.java
@@ -1,5 +1,5 @@
/* BasicInternalFrameUI.java --
- Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -57,6 +57,7 @@ import java.awt.event.ComponentListener;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
+import java.beans.PropertyVetoException;
import javax.swing.DefaultDesktopManager;
import javax.swing.DesktopManager;
@@ -168,10 +169,9 @@ public class BasicInternalFrameUI extends InternalFrameUI
implements SwingConstants
{
/**
- * If true, the cursor is being already shown in the alternative "resize"
- * shape.
+ * The current shape of the cursor.
*/
- transient boolean showingResizeCursor;
+ transient int showingCursor;
/** FIXME: Use for something. */
protected final int RESIZE_NONE = 0;
@@ -187,7 +187,7 @@ public class BasicInternalFrameUI extends InternalFrameUI
/** Cache rectangle that can be reused. */
private transient Rectangle cacheRect = new Rectangle();
-
+
/**
* This method is called when the mouse is clicked.
*
@@ -195,6 +195,20 @@ public class BasicInternalFrameUI extends InternalFrameUI
*/
public void mouseClicked(MouseEvent e)
{
+ // Do minimization/maximization when double-clicking in the title pane.
+ if (e.getSource() == titlePane && e.getClickCount() == 2)
+ try
+ {
+ if (frame.isMaximizable() && ! frame.isMaximum())
+ frame.setMaximum(true);
+ else if (frame.isMaximum())
+ frame.setMaximum(false);
+ }
+ catch (PropertyVetoException pve)
+ {
+ // We do nothing if the attempt has been vetoed.
+ }
+
// There is nothing to do when the mouse is clicked
// on the border.
}
@@ -223,34 +237,34 @@ public class BasicInternalFrameUI extends InternalFrameUI
{
switch (direction)
{
- case NORTH:
+ case Cursor.N_RESIZE_CURSOR:
cacheRect.setBounds(b.x, Math.min(b.y + y, b.y + b.height
- min.height),
b.width, b.height - y);
break;
- case NORTH_EAST:
+ case Cursor.NE_RESIZE_CURSOR:
cacheRect.setBounds(b.x, Math.min(b.y + y, b.y + b.height
- - min.height), x,
+ - min.height), x + 1,
b.height - y);
break;
- case EAST:
- cacheRect.setBounds(b.x, b.y, x, b.height);
+ case Cursor.E_RESIZE_CURSOR:
+ cacheRect.setBounds(b.x, b.y, x + 1, b.height);
break;
- case SOUTH_EAST:
- cacheRect.setBounds(b.x, b.y, x, y);
+ case Cursor.SE_RESIZE_CURSOR:
+ cacheRect.setBounds(b.x, b.y, x + 1, y + 1);
break;
- case SOUTH:
- cacheRect.setBounds(b.x, b.y, b.width, y);
+ case Cursor.S_RESIZE_CURSOR:
+ cacheRect.setBounds(b.x, b.y, b.width, y + 1);
break;
- case SOUTH_WEST:
+ case Cursor.SW_RESIZE_CURSOR:
cacheRect.setBounds(Math.min(b.x + x, b.x + b.width - min.width),
- b.y, b.width - x, y);
+ b.y, b.width - x, y + 1);
break;
- case WEST:
+ case Cursor.W_RESIZE_CURSOR:
cacheRect.setBounds(Math.min(b.x + x, b.x + b.width - min.width),
b.y, b.width - x, b.height);
break;
- case NORTH_WEST:
+ case Cursor.NW_RESIZE_CURSOR:
cacheRect.setBounds(
Math.min(b.x + x, b.x + b.width - min.width),
Math.min(b.y + y, b.y + b.height - min.height),
@@ -260,6 +274,7 @@ public class BasicInternalFrameUI extends InternalFrameUI
dm.resizeFrame(frame, cacheRect.x, cacheRect.y,
Math.max(min.width, cacheRect.width),
Math.max(min.height, cacheRect.height));
+ setCursor(e);
}
else if (e.getSource() == titlePane)
{
@@ -277,11 +292,10 @@ public class BasicInternalFrameUI extends InternalFrameUI
*/
public void mouseExited(MouseEvent e)
{
- // Reset the cursor shape.
- if (showingResizeCursor)
+ if (showingCursor != Cursor.DEFAULT_CURSOR)
{
frame.setCursor(Cursor.getDefaultCursor());
- showingResizeCursor = false;
+ showingCursor = Cursor.DEFAULT_CURSOR;
}
}
@@ -293,53 +307,36 @@ public class BasicInternalFrameUI extends InternalFrameUI
public void mouseMoved(MouseEvent e)
{
// Turn off the resize cursor if we are in the frame header.
- if (showingResizeCursor && e.getSource() != frame)
+ if (showingCursor != Cursor.DEFAULT_CURSOR && e.getSource() != frame)
{
frame.setCursor(Cursor.getDefaultCursor());
- showingResizeCursor = false;
+ showingCursor = Cursor.DEFAULT_CURSOR;
}
else if (e.getSource()==frame && frame.isResizable())
{
- int cursor;
- switch (sectionOfClick(e.getX(), e.getY()))
- {
- case NORTH:
- cursor = Cursor.N_RESIZE_CURSOR;
- break;
- case NORTH_EAST:
- cursor = Cursor.NE_RESIZE_CURSOR;
- break;
- case EAST:
- cursor = Cursor.E_RESIZE_CURSOR;
- break;
- case SOUTH_EAST:
- cursor = Cursor.SE_RESIZE_CURSOR;
- break;
- case SOUTH:
- cursor = Cursor.S_RESIZE_CURSOR;
- break;
- case SOUTH_WEST:
- cursor = Cursor.SW_RESIZE_CURSOR;
- break;
- case WEST:
- cursor = Cursor.W_RESIZE_CURSOR;
- break;
- case NORTH_WEST:
- cursor = Cursor.NW_RESIZE_CURSOR;
- break;
- default:
- cursor = Cursor.DEFAULT_CURSOR;
- }
-
+ setCursor(e);
+ }
+ }
+
+ /**
+ * Set the mouse cursor, how applicable.
+ *
+ * @param e the current mouse event.
+ */
+ void setCursor(MouseEvent e)
+ {
+ int cursor = sectionOfClick(e.getX(), e.getY());
+ if (cursor != showingCursor)
+ {
Cursor resize = Cursor.getPredefinedCursor(cursor);
frame.setCursor(resize);
- showingResizeCursor = true;
+ showingCursor = cursor;
}
}
/**
* This method is called when the mouse is pressed.
- *
+ *
* @param e The MouseEvent.
*/
public void mousePressed(MouseEvent e)
@@ -383,6 +380,8 @@ public class BasicInternalFrameUI extends InternalFrameUI
dm.endDraggingFrame(frame);
frame.putClientProperty("bufferedDragging", null);
}
+
+ setCursor(e);
}
/**
@@ -392,30 +391,31 @@ public class BasicInternalFrameUI extends InternalFrameUI
* @param x The x coordinate of the MouseEvent.
* @param y The y coordinate of the MouseEvent.
*
- * @return The direction of the resize (a SwingConstant direction).
+ * @return The cursor constant, determining the resizing direction.
*/
private int sectionOfClick(int x, int y)
{
- Insets insets = frame.getInsets();
Rectangle b = frame.getBounds();
- if (x < insets.left && y < insets.top)
- return NORTH_WEST;
- else if (x > b.width - insets.right && y < insets.top)
- return NORTH_EAST;
- else if (x > b.width - insets.right && y > b.height - insets.bottom)
- return SOUTH_EAST;
- else if (x < insets.left && y > b.height - insets.bottom)
- return SOUTH_WEST;
- else if (y < insets.top)
- return NORTH;
- else if (x < insets.left)
- return WEST;
- else if (y > b.height - insets.bottom)
- return SOUTH;
- else if (x > b.width - insets.right)
- return EAST;
-
- return -1;
+ int corner = InternalFrameBorder.cornerSize;
+
+ if (x < corner && y < corner)
+ return Cursor.NW_RESIZE_CURSOR;
+ else if (x > b.width - corner && y < corner)
+ return Cursor.NE_RESIZE_CURSOR;
+ else if (x > b.width - corner && y > b.height - corner)
+ return Cursor.SE_RESIZE_CURSOR;
+ else if (x < corner && y > b.height - corner)
+ return Cursor.SW_RESIZE_CURSOR;
+ else if (y < corner)
+ return Cursor.N_RESIZE_CURSOR;
+ else if (x < corner)
+ return Cursor.W_RESIZE_CURSOR;
+ else if (y > b.height - corner)
+ return Cursor.S_RESIZE_CURSOR;
+ else if (x > b.width - corner)
+ return Cursor.E_RESIZE_CURSOR;
+
+ return Cursor.DEFAULT_CURSOR;
}
}
@@ -992,14 +992,18 @@ public class BasicInternalFrameUI extends InternalFrameUI
/**
* This helper class is the border for the JInternalFrame.
*/
- private class InternalFrameBorder extends AbstractBorder implements
+ class InternalFrameBorder extends AbstractBorder implements
UIResource
{
- /** The width of the border. */
- private static final int bSize = 5;
+ /**
+ * The width of the border.
+ */
+ static final int bSize = 5;
- /** The size of the corners. */
- private static final int offset = 10;
+ /**
+ * The size of the corners (also used by the mouse listener).
+ */
+ static final int cornerSize = 10;
/**
* This method returns whether the border is opaque.
@@ -1069,10 +1073,12 @@ public class BasicInternalFrameUI extends InternalFrameUI
g.fillRect(0, y3, b.width, bSize);
g.fillRect(x3, 0, bSize, b.height);
- g.fill3DRect(0, offset, bSize, b.height - 2 * offset, false);
- g.fill3DRect(offset, 0, b.width - 2 * offset, bSize, false);
- g.fill3DRect(offset, b.height - bSize, b.width - 2 * offset, bSize, false);
- g.fill3DRect(b.width - bSize, offset, bSize, b.height - 2 * offset, false);
+ g.fill3DRect(0, cornerSize, bSize, b.height - 2 * cornerSize, false);
+ g.fill3DRect(cornerSize, 0, b.width - 2 * cornerSize, bSize, false);
+ g.fill3DRect(cornerSize, b.height - bSize, b.width - 2 * cornerSize,
+ bSize, false);
+ g.fill3DRect(b.width - bSize, cornerSize, bSize,
+ b.height - 2 * cornerSize, false);
g.translate(-x, -y);
g.setColor(saved);
@@ -1205,6 +1211,15 @@ public class BasicInternalFrameUI extends InternalFrameUI
frame.setLayout(internalFrameLayout);
LookAndFeel.installBorder(frame, "InternalFrame.border");
frame.setFrameIcon(UIManager.getIcon("InternalFrame.icon"));
+
+ // Let the content pane inherit the background color from its
+ // frame by setting the background to null.
+ Component contentPane = frame.getContentPane();
+ if (contentPane != null
+ && contentPane.getBackground() instanceof UIResource)
+ {
+ contentPane.setBackground(null);
+ }
}
/**
diff --git a/javax/swing/plaf/basic/BasicListUI.java b/javax/swing/plaf/basic/BasicListUI.java
index d9bc0676d..44f6a4089 100644
--- a/javax/swing/plaf/basic/BasicListUI.java
+++ b/javax/swing/plaf/basic/BasicListUI.java
@@ -218,11 +218,12 @@ public class BasicListUI extends ListUI
class ListAction extends AbstractAction
{
- public void actionPerformed (ActionEvent e)
+ public void actionPerformed(ActionEvent e)
{
int lead = list.getLeadSelectionIndex();
int max = list.getModel().getSize() - 1;
- DefaultListSelectionModel selModel = (DefaultListSelectionModel)list.getSelectionModel();
+ DefaultListSelectionModel selModel
+ = (DefaultListSelectionModel) list.getSelectionModel();
String command = e.getActionCommand();
// Do nothing if list is empty
if (max == -1)
@@ -260,9 +261,8 @@ public class BasicListUI extends ListUI
int target;
if (lead == list.getLastVisibleIndex())
{
- target = Math.min
- (max, lead + (list.getLastVisibleIndex() -
- list.getFirstVisibleIndex() + 1));
+ target = Math.min(max, lead + (list.getLastVisibleIndex()
+ - list.getFirstVisibleIndex() + 1));
}
else
target = list.getLastVisibleIndex();
@@ -273,9 +273,8 @@ public class BasicListUI extends ListUI
int target;
if (lead == list.getLastVisibleIndex())
{
- target = Math.min
- (max, lead + (list.getLastVisibleIndex() -
- list.getFirstVisibleIndex() + 1));
+ target = Math.min(max, lead + (list.getLastVisibleIndex()
+ - list.getFirstVisibleIndex() + 1));
}
else
target = list.getLastVisibleIndex();
@@ -286,9 +285,8 @@ public class BasicListUI extends ListUI
int target;
if (lead == list.getFirstVisibleIndex())
{
- target = Math.max
- (0, lead - (list.getLastVisibleIndex() -
- list.getFirstVisibleIndex() + 1));
+ target = Math.max(0, lead - (list.getLastVisibleIndex()
+ - list.getFirstVisibleIndex() + 1));
}
else
target = list.getFirstVisibleIndex();
@@ -299,9 +297,8 @@ public class BasicListUI extends ListUI
int target;
if (lead == list.getFirstVisibleIndex())
{
- target = Math.max
- (0, lead - (list.getLastVisibleIndex() -
- list.getFirstVisibleIndex() + 1));
+ target = Math.max(0, lead - (list.getLastVisibleIndex()
+ - list.getFirstVisibleIndex() + 1));
}
else
target = list.getFirstVisibleIndex();
@@ -309,32 +306,31 @@ public class BasicListUI extends ListUI
}
else if (command.equals("selectNextRowExtendSelection"))
{
- selModel.setLeadSelectionIndex(Math.min(lead + 1,max));
+ selModel.setLeadSelectionIndex(Math.min(lead + 1, max));
}
else if (command.equals("selectFirstRow"))
{
list.setSelectedIndex(0);
}
else if (command.equals("selectFirstRowChangeLead"))
- {
- selModel.moveLeadSelectionIndex(0);
- }
+ {
+ selModel.moveLeadSelectionIndex(0);
+ }
else if (command.equals("selectFirstRowExtendSelection"))
{
selModel.setLeadSelectionIndex(0);
}
else if (command.equals("selectPreviousRowExtendSelection"))
{
- selModel.setLeadSelectionIndex(Math.max(0,lead - 1));
+ selModel.setLeadSelectionIndex(Math.max(0, lead - 1));
}
else if (command.equals("scrollUp"))
{
int target;
if (lead == list.getFirstVisibleIndex())
{
- target = Math.max
- (0, lead - (list.getLastVisibleIndex() -
- list.getFirstVisibleIndex() + 1));
+ target = Math.max(0, lead - (list.getLastVisibleIndex()
+ - list.getFirstVisibleIndex() + 1));
}
else
target = list.getFirstVisibleIndex();
@@ -349,9 +345,8 @@ public class BasicListUI extends ListUI
int target;
if (lead == list.getLastVisibleIndex())
{
- target = Math.min
- (max, lead + (list.getLastVisibleIndex() -
- list.getFirstVisibleIndex() + 1));
+ target = Math.min(max, lead + (list.getLastVisibleIndex()
+ - list.getFirstVisibleIndex() + 1));
}
else
target = list.getLastVisibleIndex();
@@ -451,9 +446,9 @@ public class BasicListUI extends ListUI
if (list.getSelectionMode() == ListSelectionModel.SINGLE_SELECTION)
list.setSelectedIndex(index);
else if (list.isSelectedIndex(index))
- list.removeSelectionInterval(index,index);
+ list.removeSelectionInterval(index, index);
else
- list.addSelectionInterval(index,index);
+ list.addSelectionInterval(index, index);
}
else
list.setSelectedIndex(index);
@@ -1006,14 +1001,14 @@ public class BasicListUI extends ListUI
// Register key bindings in the UI InputMap-ActionMap pair
for (int i = 0; i < keys.length; i++)
{
- KeyStroke stroke = (KeyStroke)keys[i];
+ KeyStroke stroke = (KeyStroke) keys[i];
String actionString = (String) focusInputMap.get(stroke);
parentInputMap.put(KeyStroke.getKeyStroke(stroke.getKeyCode(),
stroke.getModifiers()),
actionString);
- parentActionMap.put (actionString,
- new ActionListenerProxy(action, actionString));
+ parentActionMap.put(actionString,
+ new ActionListenerProxy(action, actionString));
}
// Register the new InputMap-ActionMap as the parents of the list's
// InputMap and ActionMap
diff --git a/javax/swing/plaf/basic/BasicOptionPaneUI.java b/javax/swing/plaf/basic/BasicOptionPaneUI.java
index 88bca3b53..91bf61434 100644
--- a/javax/swing/plaf/basic/BasicOptionPaneUI.java
+++ b/javax/swing/plaf/basic/BasicOptionPaneUI.java
@@ -977,7 +977,7 @@ public class BasicOptionPaneUI extends OptionPaneUI
case JOptionPane.OK_CANCEL_OPTION:
return new Object[] { OK_STRING, CANCEL_STRING };
case JOptionPane.DEFAULT_OPTION:
- return (optionPane.getWantsInput() ) ?
+ return (optionPane.getWantsInput()) ?
new Object[] { OK_STRING, CANCEL_STRING } :
( optionPane.getMessageType() == JOptionPane.QUESTION_MESSAGE ) ?
new Object[] { YES_STRING, NO_STRING, CANCEL_STRING } :
diff --git a/javax/swing/plaf/basic/BasicPanelUI.java b/javax/swing/plaf/basic/BasicPanelUI.java
index 4f535f653..458f10204 100644
--- a/javax/swing/plaf/basic/BasicPanelUI.java
+++ b/javax/swing/plaf/basic/BasicPanelUI.java
@@ -1,5 +1,5 @@
/* BasicPanelUI.java
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -44,33 +44,68 @@ import javax.swing.LookAndFeel;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.PanelUI;
+/**
+ * A UI delegate for the {@link JPanel} component.
+ */
public class BasicPanelUI extends PanelUI
{
- public static ComponentUI createUI(JComponent x)
+ /**
+ * A UI delegate that can be shared by all panels (because the delegate is
+ * stateless).
+ */
+ static BasicPanelUI sharedUI;
+
+ /**
+ * Returns a UI delegate for the specified component.
+ *
+ * @param panel the panel.
+ */
+ public static ComponentUI createUI(JComponent panel)
{
- return new BasicPanelUI();
+ if (sharedUI == null)
+ sharedUI = new BasicPanelUI();
+ return sharedUI;
}
+ /**
+ * Installs this UI delegate in the specified component.
+ *
+ * @param c the component (should be a {@link JPanel}, <code>null</code> not
+ * permitted).
+ */
public void installUI(JComponent c)
{
super.installUI(c);
if (c instanceof JPanel)
{
- JPanel p = (JPanel) c;
- installDefaults(p);
+ JPanel p = (JPanel) c;
+ installDefaults(p);
}
}
+ /**
+ * Installs the defaults for this UI delegate in the specified panel.
+ *
+ * @param p the panel (<code>null</code> not permitted).
+ */
protected void installDefaults(JPanel p)
{
LookAndFeel.installColorsAndFont(p, "Panel.background", "Panel.foreground",
"Panel.font");
+
+ // A test against the reference implementation shows that this method will
+ // install a border if one is defined in the UIDefaults table (even though
+ // the BasicLookAndFeel doesn't actually define a "Panel.border"). This
+ // test was written after discovering that a null argument to
+ // uninstallDefaults throws a NullPointerException in
+ // LookAndFeel.uninstallBorder()...
+ LookAndFeel.installBorder(p, "Panel.border");
}
/**
- * Uninstalls this UI from the JPanel.
+ * Uninstalls this UI delegate from the specified component.
*
- * @param c the JPanel from which to uninstall this UI
+ * @param c the component (<code>null</code> not permitted).
*/
public void uninstallUI(JComponent c)
{
@@ -78,13 +113,20 @@ public class BasicPanelUI extends PanelUI
}
/**
- * Uninstalls the UI defaults that have been install through
- * {@link #installDefaults}.
+ * Uninstalls the UI defaults for the specified panel.
*
- * @param p the panel from which to uninstall the UI defaults
+ * @param p the panel (<code>null</code> not permitted).
*/
protected void uninstallDefaults(JPanel p)
{
- // Nothing to do here.
+ // Tests on the reference implementation showed this method:
+ // (1) doesn't actually remove the installed colors and font installed
+ // by installDefaults(), it isn't necessary;
+ // (2) throws a NullPointerException in LookAndFeel.uninstallBorder() if
+ // p is null. Strangely, no border is installed by the
+ // BasicLookAndFeel - perhaps this is needed by another LAF?
+
+ LookAndFeel.uninstallBorder(p);
}
+
}
diff --git a/javax/swing/plaf/basic/BasicProgressBarUI.java b/javax/swing/plaf/basic/BasicProgressBarUI.java
index d3674664d..ac5ec8b4f 100644
--- a/javax/swing/plaf/basic/BasicProgressBarUI.java
+++ b/javax/swing/plaf/basic/BasicProgressBarUI.java
@@ -52,6 +52,7 @@ import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
+import java.awt.geom.AffineTransform;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
@@ -725,40 +726,35 @@ public class BasicProgressBarUI extends ProgressBarUI
protected void paintString(Graphics g, int x, int y, int width, int height,
int amountFull, Insets b)
{
- // FIXME: We do not support vertical text painting because Java2D is needed
- // for this.
- if (progressBar.getOrientation() == JProgressBar.VERTICAL)
- return;
-
- // We want to place in the exact center of the bar.
+ String str = progressBar.getString();
+ int full = getAmountFull(b, width, height);
Point placement = getStringPlacement(g, progressBar.getString(),
- x + b.left, y + b.top,
+ x + b.left, y + b.top,
width - b.left - b.right,
height - b.top - b.bottom);
-
Color savedColor = g.getColor();
Shape savedClip = g.getClip();
- FontMetrics fm = g.getFontMetrics(progressBar.getFont());
- int full = getAmountFull(b, width, height);
- String str = progressBar.getString();
-
- // We draw this string two times with different clips so that the text
- // over the filled area is painted with selectionForeground and over
- // the clear area with selectionBackground.
+
+ if (progressBar.getOrientation() == JProgressBar.VERTICAL)
+ {
+ AffineTransform rotate = AffineTransform.getRotateInstance(Math.PI / 2);
+ g.setFont(progressBar.getFont().deriveFont(rotate));
+ }
+
g.setColor(getSelectionForeground());
g.setClip(0, 0, full + b.left, height);
- g.drawString(str, placement.x, placement.y + fm.getAscent());
+ g.drawString(str, placement.x, placement.y);
g.setColor(getSelectionBackground());
g.setClip(full + b.left, 0, width - full, height);
- g.drawString(str, placement.x, placement.y + fm.getAscent());
+ g.drawString(str, placement.x, placement.y);
g.setClip(savedClip);
g.setColor(savedColor);
}
/**
- * This method sets the current animation index. If the index
- * is greater than the number of frames, it resets to 0.
- *
+ * This method sets the current animation index. If the index is greater than
+ * the number of frames, it resets to 0.
+ *
* @param newValue The new animation index.
*/
protected void setAnimationIndex(int newValue)
diff --git a/javax/swing/plaf/basic/BasicRadioButtonUI.java b/javax/swing/plaf/basic/BasicRadioButtonUI.java
index a66fa28e6..64a1deca5 100644
--- a/javax/swing/plaf/basic/BasicRadioButtonUI.java
+++ b/javax/swing/plaf/basic/BasicRadioButtonUI.java
@@ -1,5 +1,5 @@
/* BasicRadioButtonUI.java
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -167,9 +167,8 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI
}
if (text != null)
paintText(g, b, tr, text);
- // TODO: Figure out what is the size parameter?
if (b.hasFocus() && b.isFocusPainted() && m.isEnabled())
- paintFocus(g, tr, null);
+ paintFocus(g, tr, c.getSize());
}
/**
@@ -177,9 +176,8 @@ public class BasicRadioButtonUI extends BasicToggleButtonUI
*
* @param g the graphics context
* @param tr the rectangle for the text label
- * @param size the size (??)
+ * @param size the size of the <code>JRadioButton</code> component.
*/
- // TODO: Figure out what for is the size parameter.
protected void paintFocus(Graphics g, Rectangle tr, Dimension size)
{
Color focusColor = UIManager.getColor(getPropertyPrefix() + ".focus");
diff --git a/javax/swing/plaf/basic/BasicRootPaneUI.java b/javax/swing/plaf/basic/BasicRootPaneUI.java
index 933db4c6b..e20bc2bb3 100644
--- a/javax/swing/plaf/basic/BasicRootPaneUI.java
+++ b/javax/swing/plaf/basic/BasicRootPaneUI.java
@@ -215,9 +215,8 @@ public class BasicRootPaneUI extends RootPaneUI
JComponent.WHEN_IN_FOCUSED_WINDOW);
if (newValue != null)
{
- Object[] keybindings =
- (Object[]) UIManager.get
- ("RootPane.defaultButtonWindowKeyBindings");
+ Object[] keybindings = (Object[]) UIManager.get(
+ "RootPane.defaultButtonWindowKeyBindings");
LookAndFeel.loadKeyBindings(im, keybindings);
}
else
diff --git a/javax/swing/plaf/basic/BasicScrollPaneUI.java b/javax/swing/plaf/basic/BasicScrollPaneUI.java
index e6a4eaf4f..9e55dbb81 100644
--- a/javax/swing/plaf/basic/BasicScrollPaneUI.java
+++ b/javax/swing/plaf/basic/BasicScrollPaneUI.java
@@ -545,7 +545,7 @@ public class BasicScrollPaneUI extends ScrollPaneUI
public void uninstallUI(final JComponent c)
{
super.uninstallUI(c);
- this.uninstallDefaults((JScrollPane)c);
+ this.uninstallDefaults((JScrollPane) c);
uninstallListeners((JScrollPane) c);
installKeyboardActions((JScrollPane) c);
}
@@ -590,7 +590,7 @@ public class BasicScrollPaneUI extends ScrollPaneUI
public Dimension getMinimumSize(JComponent c)
{
- JScrollPane p = (JScrollPane ) c;
+ JScrollPane p = (JScrollPane) c;
ScrollPaneLayout sl = (ScrollPaneLayout) p.getLayout();
return sl.minimumLayoutSize(c);
}
diff --git a/javax/swing/plaf/basic/BasicSliderUI.java b/javax/swing/plaf/basic/BasicSliderUI.java
index 137ab55a6..0569768a6 100644
--- a/javax/swing/plaf/basic/BasicSliderUI.java
+++ b/javax/swing/plaf/basic/BasicSliderUI.java
@@ -38,8 +38,6 @@ exception statement from your version. */
package javax.swing.plaf.basic;
-import gnu.classpath.NotImplementedException;
-
import java.awt.Color;
import java.awt.Component;
import java.awt.ComponentOrientation;
@@ -70,6 +68,7 @@ import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JSlider;
import javax.swing.LookAndFeel;
+import javax.swing.RepaintManager;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
@@ -209,9 +208,9 @@ public class BasicSliderUI extends SliderUI
* @param e A {@link FocusEvent}.
*/
public void focusGained(FocusEvent e)
- throws NotImplementedException
{
- // FIXME: implement.
+ slider.repaint();
+ hasFocus = true;
}
/**
@@ -221,9 +220,9 @@ public class BasicSliderUI extends SliderUI
* @param e A {@link FocusEvent}.
*/
public void focusLost(FocusEvent e)
- throws NotImplementedException
{
- // FIXME: implement.
+ slider.repaint();
+ hasFocus = false;
}
}
@@ -592,6 +591,9 @@ public class BasicSliderUI extends SliderUI
/** The focus color. */
private transient Color focusColor;
+
+ /** True if the slider has focus. */
+ private transient boolean hasFocus;
/**
* Creates a new Basic look and feel Slider UI.
@@ -1548,9 +1550,11 @@ public class BasicSliderUI extends SliderUI
paintTicks(g);
if (slider.getPaintLabels())
paintLabels(g);
-
- //FIXME: Paint focus.
+
paintThumb(g);
+
+ if (hasFocus)
+ paintFocus(g);
}
/**
@@ -1602,7 +1606,7 @@ public class BasicSliderUI extends SliderUI
Color saved_color = g.getColor();
g.setColor(getFocusColor());
-
+
g.drawRect(focusRect.x, focusRect.y, focusRect.width, focusRect.height);
g.setColor(saved_color);
@@ -1989,7 +1993,7 @@ public class BasicSliderUI extends SliderUI
public void paintThumb(Graphics g)
{
Color saved_color = g.getColor();
-
+
Point a = new Point(thumbRect.x, thumbRect.y);
Point b = new Point(a);
Point c = new Point(a);
@@ -1997,11 +2001,11 @@ public class BasicSliderUI extends SliderUI
Point e = new Point(a);
Polygon bright;
- Polygon light; // light shadow
- Polygon dark; // dark shadow
+ Polygon light; // light shadow
+ Polygon dark; // dark shadow
Polygon all;
- // This will be in X-dimension if the slider is inverted and y if it isn't.
+ // This will be in X-dimension if the slider is inverted and y if it isn't.
int turnPoint;
if (slider.getOrientation() == JSlider.HORIZONTAL)
@@ -2016,13 +2020,15 @@ public class BasicSliderUI extends SliderUI
bright = new Polygon(new int[] { b.x - 1, a.x, e.x, d.x },
new int[] { b.y, a.y, e.y, d.y }, 4);
- dark = new Polygon(new int[] { b.x, c.x, d.x + 1 },
- new int[] { b.y, c.y - 1, d.y }, 3);
-
- light = new Polygon(new int[] { b.x - 1, c.x - 1, d.x + 1 },
- new int[] { b.y + 1, c.y - 1, d.y - 1 }, 3);
-
- all = new Polygon(new int[] { a.x + 1, b.x - 2, c.x - 2, d.x, e.x + 1 },
+ dark = new Polygon(new int[] { b.x, c.x, d.x + 1 }, new int[] { b.y,
+ c.y - 1,
+ d.y }, 3);
+
+ light = new Polygon(new int[] { b.x - 1, c.x - 1, d.x + 1 },
+ new int[] { b.y + 1, c.y - 1, d.y - 1 }, 3);
+
+ all = new Polygon(
+ new int[] { a.x + 1, b.x - 2, c.x - 2, d.x, e.x + 1 },
new int[] { a.y + 1, b.y + 1, c.y - 1, d.y - 1, e.y },
5);
}
@@ -2038,15 +2044,16 @@ public class BasicSliderUI extends SliderUI
bright = new Polygon(new int[] { c.x - 1, b.x, a.x, e.x },
new int[] { c.y - 1, b.y, a.y, e.y - 1 }, 4);
- dark = new Polygon(new int[] { c.x, d.x, e.x },
- new int[] { c.y, d.y, e.y }, 3);
+ dark = new Polygon(new int[] { c.x, d.x, e.x }, new int[] { c.y, d.y,
+ e.y }, 3);
- light = new Polygon(new int[] { c.x - 1, d.x, e.x + 1},
- new int[] { c.y, d.y - 1, e.y - 1}, 3);
- all = new Polygon(new int[] { a.x + 1, b.x, c.x - 2, c.x - 2, d.x,
- e.x + 1 },
- new int[] { a.y + 1, b.y + 1, c.y - 1, c.y, d.y - 2,
- e.y - 2 }, 6);
+ light = new Polygon(new int[] { c.x - 1, d.x, e.x + 1 },
+ new int[] { c.y, d.y - 1, e.y - 1 }, 3);
+ all = new Polygon(new int[] { a.x + 1, b.x, c.x - 2, c.x - 2, d.x,
+ e.x + 1 }, new int[] { a.y + 1, b.y + 1,
+ c.y - 1, c.y,
+ d.y - 2, e.y - 2 },
+ 6);
}
g.setColor(Color.WHITE);
@@ -2057,7 +2064,7 @@ public class BasicSliderUI extends SliderUI
g.setColor(Color.GRAY);
g.drawPolyline(light.xpoints, light.ypoints, light.npoints);
-
+
g.setColor(Color.LIGHT_GRAY);
g.drawPolyline(all.xpoints, all.ypoints, all.npoints);
g.fillPolygon(all);
diff --git a/javax/swing/plaf/basic/BasicSpinnerUI.java b/javax/swing/plaf/basic/BasicSpinnerUI.java
index 465374bfd..254a9a4fa 100644
--- a/javax/swing/plaf/basic/BasicSpinnerUI.java
+++ b/javax/swing/plaf/basic/BasicSpinnerUI.java
@@ -220,7 +220,7 @@ public class BasicSpinnerUI extends SpinnerUI
BasicSpinnerUI.this.spinner.getModel().setValue(next);
}
- volatile boolean mouseDown = false;
+ volatile boolean mouseDown;
Timer timer = new Timer(50,
new ActionListener()
{
@@ -260,7 +260,7 @@ public class BasicSpinnerUI extends SpinnerUI
BasicSpinnerUI.this.spinner.getModel().setValue(prev);
}
- volatile boolean mouseDown = false;
+ volatile boolean mouseDown;
Timer timer = new Timer(50,
new ActionListener()
{
diff --git a/javax/swing/plaf/basic/BasicTabbedPaneUI.java b/javax/swing/plaf/basic/BasicTabbedPaneUI.java
index 6d9bed331..934c57fcc 100644
--- a/javax/swing/plaf/basic/BasicTabbedPaneUI.java
+++ b/javax/swing/plaf/basic/BasicTabbedPaneUI.java
@@ -286,7 +286,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
width = Math.max(min, width);
int tabAreaHeight = preferredTabAreaHeight(tabPlacement,
width - tabAreaInsets.left
- -tabAreaInsets.right);
+ - tabAreaInsets.right);
height += tabAreaHeight;
}
else
@@ -476,7 +476,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
else
nextIndex = i + 1;
int next = tabRuns[nextIndex];
- int end = (next != 0 ? next - 1 : tabCount - 1);
+ int end = next != 0 ? next - 1 : tabCount - 1;
if (tabPlacement == SwingConstants.TOP
|| tabPlacement == SwingConstants.BOTTOM)
{
@@ -491,9 +491,9 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
padTabRun(tabPlacement, start, end, breakAt);
}
if (tabPlacement == BOTTOM)
- y -= (maxTabHeight - tabRunOverlay);
+ y -= maxTabHeight - tabRunOverlay;
else
- y += (maxTabHeight - tabRunOverlay);
+ y += maxTabHeight - tabRunOverlay;
}
else
{
@@ -508,9 +508,9 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
padTabRun(tabPlacement, start, end, breakAt);
}
if (tabPlacement == RIGHT)
- x -= (maxTabWidth - tabRunOverlay);
+ x -= maxTabWidth - tabRunOverlay;
else
- x += (maxTabWidth - tabRunOverlay);
+ x += maxTabWidth - tabRunOverlay;
}
}
@@ -1818,7 +1818,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
next = tabRuns[0];
else
next = tabRuns[i + 1];
- int end = (next != 0 ? next - 1 : tabCount - 1);
+ int end = next != 0 ? next - 1 : tabCount - 1;
for (int j = start; j <= end; ++j)
{
if (j != selectedIndex)
@@ -2194,7 +2194,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
{
case LEFT:
x += calculateTabAreaWidth(tabPlacement, runCount, maxTabWidth);
- w -= (x - insets.left);
+ w -= x - insets.left;
break;
case RIGHT:
w -= calculateTabAreaWidth(tabPlacement, runCount, maxTabWidth);
@@ -2205,7 +2205,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
case TOP:
default:
y += calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight);
- h -= (y - insets.top);
+ h -= y - insets.top;
}
// Fill background if necessary.
@@ -3015,7 +3015,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
{
int currRun = getRunForTab(tabCount, tabIndex);
int offset;
- int nextRun = (forward) ? getNextTabRun(currRun) : getPreviousTabRun(currRun);
+ int nextRun = forward ? getNextTabRun(currRun) : getPreviousTabRun(currRun);
if (tabPlacement == SwingConstants.TOP
|| tabPlacement == SwingConstants.BOTTOM)
offset = rects[lastTabInRun(tabCount, nextRun)].y
diff --git a/javax/swing/plaf/basic/BasicTableHeaderUI.java b/javax/swing/plaf/basic/BasicTableHeaderUI.java
index cfbebda21..ce8846ff8 100644
--- a/javax/swing/plaf/basic/BasicTableHeaderUI.java
+++ b/javax/swing/plaf/basic/BasicTableHeaderUI.java
@@ -199,10 +199,7 @@ public class BasicTableHeaderUI extends TableHeaderUI
*/
public void mouseExited(MouseEvent e)
{
- if (header.getResizingColumn() != null && header.getResizingAllowed())
- endResizing();
- if (header.getDraggedColumn() != null && header.getReorderingAllowed())
- endDragging(null);
+ // Nothing to do.
}
/**
@@ -363,25 +360,20 @@ public class BasicTableHeaderUI extends TableHeaderUI
void endDragging(MouseEvent e)
{
header.setDraggedColumn(null);
-
- // Return if the mouse have left the header area while pressed.
- if (e == null)
- {
- header.repaint(draggingHeaderRect);
- draggingHeaderRect = null;
- return;
- }
- else
- draggingHeaderRect = null;
+ draggingHeaderRect = null;
TableColumnModel model = header.getColumnModel();
// Find where have we dragged the column.
int x = e.getX();
int p = 0;
- int col = - 1;
+
+ int col = model.getColumnCount()-1;
int n = model.getColumnCount();
+ // This loop does not find the column if the mouse if out of the
+ // right boundary of the table header. Then we make this column the
+ // rightmost column.
Scan: for (int i = 0; i < n; i++)
{
p += model.getColumn(i).getWidth();
@@ -391,8 +383,8 @@ public class BasicTableHeaderUI extends TableHeaderUI
break Scan;
}
}
- if (col >= 0)
- header.getTable().moveColumn(draggingColumnNumber, col);
+
+ header.getTable().moveColumn(draggingColumnNumber, col);
}
}
diff --git a/javax/swing/plaf/basic/BasicTableUI.java b/javax/swing/plaf/basic/BasicTableUI.java
index ef491cbf1..bd5d2d916 100644
--- a/javax/swing/plaf/basic/BasicTableUI.java
+++ b/javax/swing/plaf/basic/BasicTableUI.java
@@ -228,8 +228,6 @@ public class BasicTableUI extends TableUI
if (e.getClickCount() < ce.getClickCountToStart())
return;
}
- else if (e.getClickCount() < 2)
- return;
table.editCellAt(row, col);
}
}
@@ -428,7 +426,6 @@ public class BasicTableUI extends TableUI
table.setSelectionForeground(UIManager.getColor("Table.selectionForeground"));
table.setSelectionBackground(UIManager.getColor("Table.selectionBackground"));
table.setOpaque(true);
- rendererPane = new CellRendererPane();
}
protected void installKeyboardActions()
@@ -1188,6 +1185,9 @@ public class BasicTableUI extends TableUI
public void installUI(JComponent comp)
{
table = (JTable)comp;
+ rendererPane = new CellRendererPane();
+ table.add(rendererPane);
+
installDefaults();
installKeyboardActions();
installListeners();
@@ -1197,7 +1197,11 @@ public class BasicTableUI extends TableUI
{
uninstallListeners();
uninstallKeyboardActions();
- uninstallDefaults();
+ uninstallDefaults();
+
+ table.remove(rendererPane);
+ rendererPane = null;
+ table = null;
}
/**
@@ -1257,7 +1261,6 @@ public class BasicTableUI extends TableUI
}
Rectangle bounds = table.getCellRect(r0, c0, false);
-
// The left boundary of the area being repainted.
int left = bounds.x;
@@ -1278,9 +1281,9 @@ public class BasicTableUI extends TableUI
bounds.x += widths[c] + columnMargin;
}
bounds.x = left;
- bounds.y += table.getRowHeight(r) + rowMargin;
+ bounds.y += table.getRowHeight(r);
// Update row height for tables with custom heights.
- bounds.height = table.getRowHeight(r + 1);
+ bounds.height = table.getRowHeight(r + 1) - rowMargin;
}
bottom = bounds.y - rowMargin;
@@ -1311,7 +1314,7 @@ public class BasicTableUI extends TableUI
{
// The horizontal grid is draw below the cells, so we
// add before drawing.
- y += table.getRowHeight(r) + rowMargin;
+ y += table.getRowHeight(r);// + rowMargin;
gfx.drawLine(left, y, p2.x, y);
}
gfx.setColor(save);
diff --git a/javax/swing/plaf/basic/BasicTextAreaUI.java b/javax/swing/plaf/basic/BasicTextAreaUI.java
index 93e119b31..3f5aa27cf 100644
--- a/javax/swing/plaf/basic/BasicTextAreaUI.java
+++ b/javax/swing/plaf/basic/BasicTextAreaUI.java
@@ -73,7 +73,7 @@ public class BasicTextAreaUI extends BasicTextUI
*/
public View create(Element elem)
{
- JTextArea comp = (JTextArea)getComponent();
+ JTextArea comp = (JTextArea) getComponent();
if (comp.getLineWrap())
{
if (comp.getWrapStyleWord())
@@ -105,7 +105,7 @@ public class BasicTextAreaUI extends BasicTextUI
*/
protected void propertyChange(PropertyChangeEvent ev)
{
- JTextArea comp = (JTextArea)getComponent();
+ JTextArea comp = (JTextArea) getComponent();
if (ev.getPropertyName() == "lineWrap"
|| ev.getPropertyName() == "wrapStyleWord")
{
diff --git a/javax/swing/plaf/basic/BasicTextUI.java b/javax/swing/plaf/basic/BasicTextUI.java
index 3b620f049..60c5194da 100644
--- a/javax/swing/plaf/basic/BasicTextUI.java
+++ b/javax/swing/plaf/basic/BasicTextUI.java
@@ -38,8 +38,6 @@ exception statement from your version. */
package javax.swing.plaf.basic;
-import gnu.classpath.NotImplementedException;
-
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
@@ -831,9 +829,9 @@ public abstract class BasicTextUI extends TextUI
* this UI.
*/
protected void uninstallKeyboardActions()
- throws NotImplementedException
{
- // FIXME: Uninstall keyboard actions here.
+ SwingUtilities.replaceUIInputMap(textComponent, JComponent.WHEN_FOCUSED, null);
+ SwingUtilities.replaceUIActionMap(textComponent, null);
}
/**
@@ -1041,7 +1039,12 @@ public abstract class BasicTextUI extends TextUI
Rectangle l1 = modelToView(t, p0, firstBias);
Rectangle l2 = modelToView(t, p1, secondBias);
- if (l1.y == l2.y)
+ if (l1 == null || l2 == null)
+ {
+ // Unable to determine the start or end of the selection.
+ t.repaint();
+ }
+ else if (l1.y == l2.y)
{
SwingUtilities.computeUnion(l2.x, l2.y, l2.width, l2.height, l1);
t.repaint(l1);
diff --git a/javax/swing/plaf/basic/BasicToggleButtonUI.java b/javax/swing/plaf/basic/BasicToggleButtonUI.java
index 896ea0c89..921648670 100644
--- a/javax/swing/plaf/basic/BasicToggleButtonUI.java
+++ b/javax/swing/plaf/basic/BasicToggleButtonUI.java
@@ -1,5 +1,5 @@
/* BasicToggleButtonUI.java
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -44,21 +44,35 @@ import java.awt.Rectangle;
import javax.swing.AbstractButton;
import javax.swing.JComponent;
+import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
+/**
+ * A UI delegate for the {@link JToggleButton} component.
+ */
public class BasicToggleButtonUI extends BasicButtonUI
{
- public static ComponentUI createUI(final JComponent component)
+
+ /**
+ * Returns a UI delegate for the specified component.
+ *
+ * @param component the component (should be an instance of
+ * {@link JToggleButton}).
+ *
+ * @return An instance of <code>BasicToggleButtonUI</code>.
+ */
+ public static ComponentUI createUI(JComponent component)
{
return new BasicToggleButtonUI();
}
/**
- * Returns the prefix for the UI defaults property for this UI class.
- * This is &apos;ToggleButton&apos; for this class.
+ * Returns the prefix for entries in the {@link UIManager} defaults table
+ * (<code>"ToggleButton."</code> in this case).
*
- * @return the prefix for the UI defaults property
+ * @return <code>"ToggleButton."</code>
*/
protected String getPropertyPrefix()
{
@@ -89,15 +103,10 @@ public class BasicToggleButtonUI extends BasicButtonUI
else
vr = SwingUtilities.getLocalBounds(b);
String text = SwingUtilities.layoutCompoundLabel(c, g.getFontMetrics(f),
- b.getText(),
- currentIcon(b),
- b.getVerticalAlignment(),
- b.getHorizontalAlignment(),
- b.getVerticalTextPosition(),
- b.getHorizontalTextPosition(),
- vr, ir, tr,
- b.getIconTextGap()
- + defaultTextShiftOffset);
+ b.getText(), currentIcon(b), b.getVerticalAlignment(),
+ b.getHorizontalAlignment(), b.getVerticalTextPosition(),
+ b.getHorizontalTextPosition(), vr, ir, tr, b.getIconTextGap()
+ + defaultTextShiftOffset);
if ((b.getModel().isArmed() && b.getModel().isPressed())
|| b.isSelected())
diff --git a/javax/swing/plaf/basic/BasicToolBarUI.java b/javax/swing/plaf/basic/BasicToolBarUI.java
index 80fec6a77..eabac1570 100644
--- a/javax/swing/plaf/basic/BasicToolBarUI.java
+++ b/javax/swing/plaf/basic/BasicToolBarUI.java
@@ -1,5 +1,5 @@
/* BasicToolBarUI.java --
- Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -75,11 +75,12 @@ import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.Border;
-import javax.swing.border.EtchedBorder;
+import javax.swing.border.CompoundBorder;
import javax.swing.event.MouseInputListener;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.ToolBarUI;
import javax.swing.plaf.UIResource;
+import javax.swing.plaf.basic.BasicBorders.ButtonBorder;
/**
* This is the Basic Look and Feel UI class for JToolBar.
@@ -310,8 +311,19 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants
*/
protected Border createNonRolloverBorder()
{
- return new EtchedBorder();
- }
+ Border b = UIManager.getBorder("ToolBar.nonrolloverBorder");
+
+ if (b == null)
+ {
+ b = new CompoundBorder(
+ new ButtonBorder(UIManager.getColor("Button.shadow"),
+ UIManager.getColor("Button.darkShadow"),
+ UIManager.getColor("Button.light"),
+ UIManager.getColor("Button.highlight")),
+ BasicBorders.getMarginBorder());
+ }
+
+ return b; }
/**
* This method creates a new PropertyChangeListener for the JToolBar.
@@ -331,18 +343,19 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants
*/
protected Border createRolloverBorder()
{
- return new EtchedBorder()
+ Border b = UIManager.getBorder("ToolBar.rolloverBorder");
+
+ if (b == null)
{
- public void paintBorder(Component c, Graphics g, int x, int y,
- int width, int height)
- {
- if (c instanceof JButton)
- {
- if (((JButton) c).getModel().isRollover())
- super.paintBorder(c, g, x, y, width, height);
- }
- }
- };
+ b = new CompoundBorder(
+ new ButtonBorder(UIManager.getColor("Button.shadow"),
+ UIManager.getColor("Button.darkShadow"),
+ UIManager.getColor("Button.light"),
+ UIManager.getColor("Button.highlight")),
+ BasicBorders.getMarginBorder());
+ }
+
+ return b;
}
/**
@@ -745,6 +758,7 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants
* @param direction The direction to give focus to.
*/
protected void navigateFocusedComp(int direction)
+ throws NotImplementedException
{
// FIXME: Implement.
}
@@ -761,6 +775,10 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants
{
AbstractButton b = (AbstractButton) c;
b.setRolloverEnabled(false);
+
+ // Save old border in hashtable.
+ borders.put(b, b.getBorder());
+
b.setBorder(nonRolloverBorder);
}
}
@@ -772,11 +790,11 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants
*/
protected void setBorderToNormal(Component c)
{
- if (c instanceof JButton)
+ if (c instanceof AbstractButton)
{
- JButton b = (JButton) c;
- Border border = (Border) borders.get(b);
- b.setBorder(border);
+ AbstractButton b = (AbstractButton) c;
+ b.setRolloverEnabled(true);
+ b.setBorder((Border) borders.remove(b));
}
}
@@ -787,11 +805,15 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants
*/
protected void setBorderToRollover(Component c)
{
- if (c instanceof JButton)
+ if (c instanceof AbstractButton)
{
- JButton b = (JButton) c;
- b.setRolloverEnabled(true);
- b.setBorder(rolloverBorder);
+ AbstractButton b = (AbstractButton) c;
+ b.setRolloverEnabled(false);
+
+ // Save old border in hashtable.
+ borders.put(b, b.getBorder());
+
+ b.setBorder(rolloverBorder);
}
}
diff --git a/javax/swing/plaf/basic/BasicTreeUI.java b/javax/swing/plaf/basic/BasicTreeUI.java
index a143a962b..b7d293e2f 100644
--- a/javax/swing/plaf/basic/BasicTreeUI.java
+++ b/javax/swing/plaf/basic/BasicTreeUI.java
@@ -38,6 +38,7 @@
package javax.swing.plaf.basic;
+import gnu.classpath.NotImplementedException;
import gnu.javax.swing.tree.GnuPath;
import java.awt.Color;
@@ -98,7 +99,6 @@ import javax.swing.plaf.ActionMapUIResource;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.InputMapUIResource;
import javax.swing.plaf.TreeUI;
-import javax.swing.plaf.metal.MetalIconFactory;
import javax.swing.tree.AbstractLayoutCache;
import javax.swing.tree.DefaultTreeCellEditor;
import javax.swing.tree.DefaultTreeCellRenderer;
@@ -252,6 +252,9 @@ public class BasicTreeUI
/** The max height of the nodes in the tree. */
int maxHeight = 0;
+
+ /** The hash color. */
+ Color hashColor;
/** Listeners */
PropertyChangeListener propertyChangeListener;
@@ -337,7 +340,7 @@ public class BasicTreeUI
*/
protected Color getHashColor()
{
- return UIManager.getColor("Tree.hash");
+ return hashColor;
}
/**
@@ -347,8 +350,7 @@ public class BasicTreeUI
*/
protected void setHashColor(Color color)
{
- // FIXME: Putting something in the UIDefaults map is certainly wrong.
- UIManager.put("Tree.hash", color);
+ hashColor = color;
}
/**
@@ -820,6 +822,7 @@ public class BasicTreeUI
* default/listeners have been installed.
*/
protected void prepareForUIInstall()
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
@@ -829,6 +832,7 @@ public class BasicTreeUI
* installed.
*/
protected void completeUIInstall()
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
@@ -838,6 +842,7 @@ public class BasicTreeUI
* uninstalled.
*/
protected void completeUIUninstall()
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
@@ -1803,7 +1808,9 @@ public class BasicTreeUI
* the event.
*/
protected boolean isToggleEvent(MouseEvent event)
+ throws NotImplementedException
{
+ // FIXME: Not implemented.
return true;
}
@@ -1986,6 +1993,7 @@ public class BasicTreeUI
* @param e the event that occurs when moving the component
*/
public void componentMoved(ComponentEvent e)
+ throws NotImplementedException
{
// TODO: What should be done here, if anything?
}
@@ -1995,6 +2003,7 @@ public class BasicTreeUI
* the bounds
*/
protected void startTimer()
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
@@ -2005,7 +2014,9 @@ public class BasicTreeUI
* @return JScrollPane housing the JTree, or null if one isn't found.
*/
protected JScrollPane getScrollPane()
+ throws NotImplementedException
{
+ // FIXME: Not implemented.
return null;
}
@@ -2016,6 +2027,7 @@ public class BasicTreeUI
* @param ae is the action performed
*/
public void actionPerformed(ActionEvent ae)
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
@@ -2140,6 +2152,7 @@ public class BasicTreeUI
* @param e the key typed
*/
public void keyTyped(KeyEvent e)
+ throws NotImplementedException
{
// TODO: What should be done here, if anything?
}
@@ -2150,6 +2163,7 @@ public class BasicTreeUI
* @param e the key pressed
*/
public void keyPressed(KeyEvent e)
+ throws NotImplementedException
{
// TODO: What should be done here, if anything?
}
@@ -2160,6 +2174,7 @@ public class BasicTreeUI
* @param e the key released
*/
public void keyReleased(KeyEvent e)
+ throws NotImplementedException
{
// TODO: What should be done here, if anything?
}
@@ -2289,6 +2304,7 @@ public class BasicTreeUI
* @param e is the mouse event that occured
*/
public void mouseDragged(MouseEvent e)
+ throws NotImplementedException
{
// TODO: What should be done here, if anything?
}
@@ -2300,6 +2316,7 @@ public class BasicTreeUI
* @param e the mouse event that occured
*/
public void mouseMoved(MouseEvent e)
+ throws NotImplementedException
{
// TODO: What should be done here, if anything?
}
@@ -2310,6 +2327,7 @@ public class BasicTreeUI
* @param e is the mouse event that occured
*/
public void mouseReleased(MouseEvent e)
+ throws NotImplementedException
{
// TODO: What should be done here, if anything?
}
@@ -2350,6 +2368,7 @@ public class BasicTreeUI
* @param e mouse event that occured
*/
public void mouseClicked(MouseEvent e)
+ throws NotImplementedException
{
// TODO: What should be done here, if anything?
}
@@ -2360,6 +2379,7 @@ public class BasicTreeUI
* @param e mouse event that occured
*/
public void mousePressed(MouseEvent e)
+ throws NotImplementedException
{
// TODO: What should be done here, if anything?
}
@@ -2370,6 +2390,7 @@ public class BasicTreeUI
* @param e mouse event that occured
*/
public void mouseReleased(MouseEvent e)
+ throws NotImplementedException
{
// TODO: What should be done here, if anything?
}
@@ -2380,6 +2401,7 @@ public class BasicTreeUI
* @param e mouse event that occured
*/
public void mouseEntered(MouseEvent e)
+ throws NotImplementedException
{
// TODO: What should be done here, if anything?
}
@@ -2390,6 +2412,7 @@ public class BasicTreeUI
* @param e mouse event that occured
*/
public void mouseExited(MouseEvent e)
+ throws NotImplementedException
{
// TODO: What should be done here, if anything?
}
@@ -2403,6 +2426,7 @@ public class BasicTreeUI
* @param e mouse event that occured
*/
public void mouseDragged(MouseEvent e)
+ throws NotImplementedException
{
// TODO: What should be done here, if anything?
}
@@ -2414,6 +2438,7 @@ public class BasicTreeUI
* @param e mouse event that occured
*/
public void mouseMoved(MouseEvent e)
+ throws NotImplementedException
{
// TODO: What should be done here, if anything?
}
@@ -2422,6 +2447,7 @@ public class BasicTreeUI
* Removes event from the source
*/
protected void removeFromSource()
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
@@ -2487,7 +2513,7 @@ public class BasicTreeUI
*/
protected int getRowX(int row, int depth)
{
- return depth * totalChildIndent;
+ return BasicTreeUI.this.getRowX(row, depth);
}
}// NodeDimensionsHandler
@@ -2558,45 +2584,38 @@ public class BasicTreeUI
* the property that has changed.
*/
public void propertyChange(PropertyChangeEvent event)
+ throws NotImplementedException
{
// TODO: What should be done here, if anything?
}
}
/**
- * ActionListener that invokes cancelEditing when action performed.
+ * The action to cancel editing on this tree.
*/
public class TreeCancelEditingAction
extends AbstractAction
{
-
/**
- * Constructor
+ * Creates the new tree cancel editing action.
+ *
+ * @param name the name of the action (used in toString).
*/
public TreeCancelEditingAction(String name)
{
- // TODO: Implement this properly.
+ super(name);
}
/**
- * Invoked when an action occurs.
+ * Invoked when an action occurs, cancels the cell editing (if the
+ * tree cell is being edited).
*
* @param e event that occured
*/
public void actionPerformed(ActionEvent e)
{
- // TODO: Implement this properly.
- }
-
- /**
- * Returns true if the action is enabled.
- *
- * @return true if the action is enabled, false otherwise
- */
- public boolean isEnabled()
- {
- // TODO: Implement this properly.
- return false;
+ if (isEnabled() && tree.isEditing())
+ tree.cancelEditing();
}
}
@@ -2664,6 +2683,7 @@ public class BasicTreeUI
* @param name is the name of the direction
*/
public TreeHomeAction(int direction, String name)
+ throws NotImplementedException
{
// TODO: Implement this properly
}
@@ -2674,6 +2694,7 @@ public class BasicTreeUI
* @param e is the event that occured
*/
public void actionPerformed(ActionEvent e)
+ throws NotImplementedException
{
// TODO: Implement this properly
}
@@ -2684,6 +2705,7 @@ public class BasicTreeUI
* @return true if the action is enabled.
*/
public boolean isEnabled()
+ throws NotImplementedException
{
// TODO: Implement this properly
return false;
@@ -2708,6 +2730,7 @@ public class BasicTreeUI
* @param name is the name of the direction
*/
public TreeIncrementAction(int direction, String name)
+ throws NotImplementedException
{
// TODO: Implement this properly
}
@@ -2797,6 +2820,7 @@ public class BasicTreeUI
* @return true if the action is enabled.
*/
public boolean isEnabled()
+ throws NotImplementedException
{
// TODO: Implement this properly
return false;
@@ -2913,6 +2937,7 @@ public class BasicTreeUI
* @param e is the event that occured
*/
public void actionPerformed(ActionEvent e)
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
@@ -2923,7 +2948,9 @@ public class BasicTreeUI
* @return true if the action is enabled.
*/
public boolean isEnabled()
+ throws NotImplementedException
{
+ // FIXME: Not implemented.
return false;
}
}// TreePageAction
@@ -2995,6 +3022,7 @@ public class BasicTreeUI
* @param e the event that occured
*/
public void actionPerformed(ActionEvent e)
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
@@ -3005,7 +3033,9 @@ public class BasicTreeUI
* @return true if the action is enabled, false otherwise
*/
public boolean isEnabled()
+ throws NotImplementedException
{
+ // FIXME: Not implemented.
return false;
}
} // TreeToggleAction
@@ -3089,6 +3119,7 @@ public class BasicTreeUI
* @return true if the action is enabled, false otherwise
*/
public boolean isEnabled()
+ throws NotImplementedException
{
// TODO: Implement this properly
return false;
@@ -3443,6 +3474,7 @@ public class BasicTreeUI
* Prepares for the UI to uninstall.
*/
protected void prepareForUIUninstall()
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
@@ -3484,4 +3516,14 @@ public class BasicTreeUI
editingComponent = null;
tree.requestFocus();
}
+
+ /**
+ * Returns the amount to indent the given row
+ *
+ * @return amount to indent the given row.
+ */
+ protected int getRowX(int row, int depth)
+ {
+ return depth * totalChildIndent;
+ }
} // BasicTreeUI
diff --git a/javax/swing/plaf/metal/MetalBorders.java b/javax/swing/plaf/metal/MetalBorders.java
index 98a00ee0a..7c41180ae 100644
--- a/javax/swing/plaf/metal/MetalBorders.java
+++ b/javax/swing/plaf/metal/MetalBorders.java
@@ -103,7 +103,16 @@ public class MetalBorders
private static BasicBorders.MarginBorder marginBorder;
/**
- * A border used for {@link JButton} components.
+ * <p>A border used for {@link JButton} components.</p>
+ *
+ * <p>This {@link Border} implementation can handle only instances of
+ * {@link AbstractButton} and their subclasses.</p>
+ *
+ * <p>If the Metal Look and Feel's current theme is 'Ocean' the border
+ * will be painted with a special highlight when the mouse cursor if
+ * over the button (ie. the property <code>rollover</code> of the
+ * button's model is <code>true</code>) and is not a <b>direct</b>
+ * child of a {@link JToolBar}.</p>
*/
public static class ButtonBorder extends AbstractBorder implements UIResource
{
@@ -157,8 +166,14 @@ public class MetalBorders
{
ButtonModel bmodel = null;
+ // The RI will fail with a ClassCastException in such a situation.
+ // This code tries to be more helpful.
if (c instanceof AbstractButton)
bmodel = ((AbstractButton) c).getModel();
+ else
+ throw new IllegalStateException("A ButtonBorder is supposed to work "
+ + "only with AbstractButton and"
+ + "subclasses.");
Color darkShadow = MetalLookAndFeel.getControlDarkShadow();
Color shadow = MetalLookAndFeel.getControlShadow();
@@ -191,7 +206,7 @@ public class MetalBorders
{
// The normal border. This is used when the button is not
// pressed or the button is not armed.
- if (! (bmodel.isPressed() && bmodel.isArmed()) )
+ if (! (bmodel.isPressed() && bmodel.isArmed()))
{
// draw light border
g.setColor(light);
@@ -246,8 +261,14 @@ public class MetalBorders
{
ButtonModel bmodel = null;
+ // The RI will fail with a ClassCastException in such a situation.
+ // This code tries to be more helpful.
if (c instanceof AbstractButton)
bmodel = ((AbstractButton) c).getModel();
+ else
+ throw new IllegalStateException("A ButtonBorder is supposed to work "
+ + "only with AbstractButton and"
+ + "subclasses.");
Color darkShadow = MetalLookAndFeel.getControlDarkShadow();
Color shadow = MetalLookAndFeel.getControlShadow();
@@ -267,8 +288,10 @@ public class MetalBorders
g.drawRect(x, y, w - 1, h - 1);
g.drawRect(x + 1, y + 1, w - 3, h - 3);
}
- else if (bmodel.isRollover())
+ else if (bmodel.isRollover() && !(c.getParent() instanceof JToolBar))
{
+ // Paint a bigger border when the mouse is over the button but
+ // only if it is *not* part of a JToolBar.
g.setColor(shadow);
g.drawRect(x, y, w - 1, h - 1);
g.drawRect(x + 2, y + 2, w - 5, h - 5);
@@ -568,12 +591,12 @@ public class MetalBorders
{
boolean enabledTextBorder;
if (c instanceof JTextComponent)
- {
- JTextComponent tc = (JTextComponent) c;
- enabledTextBorder = tc.isEnabled() && tc.isEditable();
- }
+ {
+ JTextComponent tc = (JTextComponent) c;
+ enabledTextBorder = tc.isEnabled() && tc.isEditable();
+ }
else
- enabledTextBorder = false;
+ enabledTextBorder = false;
if (enabledTextBorder)
super.paintBorder(c, g, x, y, w, h);
@@ -829,35 +852,36 @@ public class MetalBorders
{
Color dark = MetalLookAndFeel.getPrimaryControlDarkShadow();
Color light = MetalLookAndFeel.getPrimaryControlHighlight();
- if (c instanceof JMenu) {
- JMenu menu = (JMenu) c;
- if (menu.isSelected())
+ if (c instanceof JMenu)
{
- g.setColor(dark);
- g.drawLine(x, y, x, y + h);
- g.drawLine(x, y, x + w, y);
- g.drawLine(x + w - 2, y + 1, x + w - 2, y + h);
- g.setColor(light);
- g.drawLine(x + w - 1, y + 1, x + w - 1, y + h);
+ JMenu menu = (JMenu) c;
+ if (menu.isSelected())
+ {
+ g.setColor(dark);
+ g.drawLine(x, y, x, y + h);
+ g.drawLine(x, y, x + w, y);
+ g.drawLine(x + w - 2, y + 1, x + w - 2, y + h);
+ g.setColor(light);
+ g.drawLine(x + w - 1, y + 1, x + w - 1, y + h);
+ }
}
- }
else if (c instanceof JMenuItem)
- {
- JMenuItem item = (JMenuItem) c;
- if (item.isArmed())
- {
- g.setColor(dark);
- g.drawLine(x, y, x + w, y);
- g.setColor(light);
- g.drawLine(x, y + h - 1, x + w, y + h - 1);
- }
- else
- {
- // Normally we draw a light line on the left.
- g.setColor(light);
- g.drawLine(x, y, x, y + h);
- }
- }
+ {
+ JMenuItem item = (JMenuItem) c;
+ if (item.isArmed())
+ {
+ g.setColor(dark);
+ g.drawLine(x, y, x + w, y);
+ g.setColor(light);
+ g.drawLine(x, y + h - 1, x + w, y + h - 1);
+ }
+ else
+ {
+ // Normally we draw a light line on the left.
+ g.setColor(light);
+ g.drawLine(x, y, x, y + h);
+ }
+ }
}
/**
@@ -1469,8 +1493,8 @@ public class MetalBorders
{
Border outer = new ButtonBorder();
Border inner = getMarginBorder();
- buttonBorder = new BorderUIResource.CompoundBorderUIResource
- (outer, inner);
+ buttonBorder = new BorderUIResource.CompoundBorderUIResource(outer,
+ inner);
}
return buttonBorder;
}
@@ -1488,8 +1512,8 @@ public class MetalBorders
{
Border outer = new ToggleButtonBorder();
Border inner = getMarginBorder();
- toggleButtonBorder = new BorderUIResource.CompoundBorderUIResource
- (outer, inner);
+ toggleButtonBorder = new BorderUIResource.CompoundBorderUIResource(
+ outer, inner);
}
return toggleButtonBorder;
}
diff --git a/javax/swing/plaf/metal/MetalButtonUI.java b/javax/swing/plaf/metal/MetalButtonUI.java
index 83cd33662..d6cc1bc07 100644
--- a/javax/swing/plaf/metal/MetalButtonUI.java
+++ b/javax/swing/plaf/metal/MetalButtonUI.java
@@ -39,6 +39,7 @@ exception statement from your version. */
package javax.swing.plaf.metal;
import java.awt.Color;
+import java.awt.Container;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
@@ -48,7 +49,9 @@ import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.JButton;
import javax.swing.JComponent;
+import javax.swing.JToolBar;
import javax.swing.SwingConstants;
+import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
@@ -121,7 +124,8 @@ public class MetalButtonUI
*
* @return A new instance of <code>MetalButtonUI</code>.
*/
- public static ComponentUI createUI(JComponent c) {
+ public static ComponentUI createUI(JComponent c)
+ {
return new MetalButtonUI();
}
@@ -187,7 +191,8 @@ public class MetalButtonUI
* @param iconRect the icon bounds.
*/
protected void paintFocus(Graphics g, AbstractButton b, Rectangle viewRect,
- Rectangle textRect, Rectangle iconRect) {
+ Rectangle textRect, Rectangle iconRect)
+ {
if (b.isEnabled() && b.hasFocus() && b.isFocusPainted())
{
Color savedColor = g.getColor();
@@ -235,19 +240,63 @@ public class MetalButtonUI
public void update(Graphics g, JComponent c)
{
AbstractButton b = (AbstractButton) c;
- ButtonModel m = b.getModel();
if (b.isContentAreaFilled()
&& (UIManager.get(getPropertyPrefix() + "gradient") != null)
- && ! m.isPressed() && ! m.isArmed()
&& b.isEnabled()
&& (b.getBackground() instanceof UIResource))
+ updateWidthGradient(g, b, b.getParent());
+ else
+ super.update(g, c);
+ }
+
+ private void updateWidthGradient(Graphics g, AbstractButton b, Container parent)
+ {
+ ButtonModel m = b.getModel();
+ String gradientPropertyName = getPropertyPrefix() + "gradient";
+
+ // Gradient painting behavior depends on whether the button is part of a
+ // JToolBar.
+ if (parent instanceof JToolBar)
+ {
+ if (! m.isPressed() && ! m.isArmed())
+ {
+ if (m.isRollover())
+ {
+ // Paint the gradient when the mouse cursor hovers over the
+ // button but is not pressed down.
+ MetalUtils.paintGradient(g, 0, 0, b.getWidth(), b.getHeight(),
+ SwingConstants.VERTICAL,
+ gradientPropertyName);
+ }
+ else
+ {
+ // If mouse does not hover over the button let the JToolBar
+ // paint itself at the location where the button is (the button
+ // is transparent).
+
+ // There where cases where the button was not repainted and
+ // therefore showed its old state. With this statement it does
+ // not happen.
+ b.repaint();
+
+ Rectangle area = new Rectangle();
+ SwingUtilities.calculateInnerArea(b, area);
+ SwingUtilities.convertRectangle(b, area, b.getParent());
+ b.getParent().repaint(area.x, area.y, area.width, area.height);
+ }
+ }
+
+ }
+ else if (! m.isPressed() && ! m.isArmed())
{
- MetalUtils.paintGradient(g, 0, 0, c.getWidth(), c.getHeight(),
+ // When the button is not part of a JToolBar just paint itself with a
+ // gradient and everything is fine.
+ MetalUtils.paintGradient(g, 0, 0, b.getWidth(), b.getHeight(),
SwingConstants.VERTICAL,
- getPropertyPrefix() + "gradient");
- paint(g, c);
+ gradientPropertyName);
}
- else
- super.update(g, c);
+
+ paint(g, b);
}
+
}
diff --git a/javax/swing/plaf/metal/MetalCheckBoxUI.java b/javax/swing/plaf/metal/MetalCheckBoxUI.java
index b4f6f0a56..c7941642e 100644
--- a/javax/swing/plaf/metal/MetalCheckBoxUI.java
+++ b/javax/swing/plaf/metal/MetalCheckBoxUI.java
@@ -52,7 +52,7 @@ public class MetalCheckBoxUI
// FIXME: maybe replace by a Map of instances when this becomes stateful
/** The shared UI instance for JCheckBoxes. */
- private static MetalCheckBoxUI instance = null;
+ private static MetalCheckBoxUI instance;
/**
* Constructs a new instance of MetalCheckBoxUI.
diff --git a/javax/swing/plaf/metal/MetalComboBoxButton.java b/javax/swing/plaf/metal/MetalComboBoxButton.java
index 3787a98c3..6a528de2b 100644
--- a/javax/swing/plaf/metal/MetalComboBoxButton.java
+++ b/javax/swing/plaf/metal/MetalComboBoxButton.java
@@ -256,9 +256,8 @@ public class MetalComboBoxButton
{
ListCellRenderer renderer = comboBox.getRenderer();
boolean pressed = this.getModel().isPressed();
- Component comp= renderer.getListCellRendererComponent(listBox,
- comboBox.getSelectedItem(),
- -1, false, false);
+ Component comp = renderer.getListCellRendererComponent(listBox,
+ comboBox.getSelectedItem(), -1, false, false);
comp.setFont(rendererPane.getFont());
if (model.isArmed() && model.isPressed())
{
diff --git a/javax/swing/plaf/metal/MetalComboBoxIcon.java b/javax/swing/plaf/metal/MetalComboBoxIcon.java
index f21c5af61..944ce3944 100644
--- a/javax/swing/plaf/metal/MetalComboBoxIcon.java
+++ b/javax/swing/plaf/metal/MetalComboBoxIcon.java
@@ -48,7 +48,8 @@ import javax.swing.Icon;
/**
* An icon used by the {@link MetalComboBoxUI} class.
*/
-public class MetalComboBoxIcon implements Icon, Serializable {
+public class MetalComboBoxIcon implements Icon, Serializable
+{
/**
* Creates a new icon.
diff --git a/javax/swing/plaf/metal/MetalFileChooserUI.java b/javax/swing/plaf/metal/MetalFileChooserUI.java
index cb94c87b8..1219ad9fd 100644
--- a/javax/swing/plaf/metal/MetalFileChooserUI.java
+++ b/javax/swing/plaf/metal/MetalFileChooserUI.java
@@ -52,12 +52,13 @@ import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
-import java.text.NumberFormat;
-
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
-
import java.io.File;
+import java.sql.Date;
+import java.text.DateFormat;
+import java.text.NumberFormat;
+import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.AbstractListModel;
@@ -79,7 +80,6 @@ import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
-import javax.swing.JViewport;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
@@ -94,12 +94,6 @@ import javax.swing.plaf.basic.BasicFileChooserUI;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
-import java.sql.Date;
-
-import java.text.DateFormat;
-
-import java.util.List;
-
/**
* A UI delegate for the {@link JFileChooser} component. This class is only
@@ -350,7 +344,7 @@ public class MetalFileChooserUI
setDirectorySelected(false);
File currentDirectory = filechooser.getCurrentDirectory();
setDirectory(currentDirectory);
- boolean hasParent = (currentDirectory.getParentFile() != null);
+ boolean hasParent = currentDirectory.getParentFile() != null;
getChangeToParentDirectoryAction().setEnabled(hasParent);
}
@@ -648,15 +642,15 @@ public class MetalFileChooserUI
FileView v = getFileView(getFileChooser());
File f = (File) value;
if (f != null)
- {
- setText(v.getName(f));
- setIcon(v.getIcon(f));
- }
+ {
+ setText(v.getName(f));
+ setIcon(v.getIcon(f));
+ }
else
- {
- setText("");
- setIcon(null);
- }
+ {
+ setText("");
+ setIcon(null);
+ }
setOpaque(true);
if (isSelected)
{
@@ -962,10 +956,9 @@ public class MetalFileChooserUI
{
String text = editField.getText();
if (text != null && text != "" && !text.equals(fc.getName(editFile)))
- if (editFile.renameTo
- (fc.getFileSystemView().createFileObject
- (fc.getCurrentDirectory(), text)))
- rescanCurrentDirectory(fc);
+ if (editFile.renameTo(fc.getFileSystemView().createFileObject(
+ fc.getCurrentDirectory(), text)))
+ rescanCurrentDirectory(fc);
list.remove(editField);
}
startEditing = false;
@@ -1018,7 +1011,7 @@ public class MetalFileChooserUI
JFileChooser fc;
/** The last selected file. */
- Object lastSelected = null;
+ Object lastSelected;
/**
* Stores the current file that is being edited.
@@ -1032,10 +1025,8 @@ public class MetalFileChooserUI
/**
* Creates a new listener.
*
- * @param table
- * the directory/file table
- * @param fc
- * the JFileChooser
+ * @param table the directory/file table
+ * @param fc the JFileChooser
*/
public TableClickListener(JTable table, JFileChooser fc)
{
@@ -1051,8 +1042,7 @@ public class MetalFileChooserUI
/**
* Receives notification of a mouse click event.
*
- * @param e
- * the event.
+ * @param e the event.
*/
public void mouseClicked(MouseEvent e)
{
@@ -1156,10 +1146,9 @@ public class MetalFileChooserUI
{
String text = editField.getText();
if (text != null && text != "" && !text.equals(fc.getName(editFile)))
- if (editFile.renameTo
- (fc.getFileSystemView().createFileObject
- (fc.getCurrentDirectory(), text)))
- rescanCurrentDirectory(fc);
+ if (editFile.renameTo(fc.getFileSystemView().createFileObject(
+ fc.getCurrentDirectory(), text)))
+ rescanCurrentDirectory(fc);
table.remove(editField);
}
startEditing = false;
@@ -1636,8 +1625,7 @@ public class MetalFileChooserUI
/**
* Formats bytes into the appropriate size.
*
- * @param bytes -
- * the number of bytes to convert
+ * @param bytes the number of bytes to convert
* @return a string representation of the size
*/
private String formatSize(long bytes)
@@ -1838,7 +1826,7 @@ public class MetalFileChooserUI
/**
* Updates the current directory.
*
- * @param the file chooser to update.
+ * @param fc the file chooser to update.
*/
public void rescanCurrentDirectory(JFileChooser fc)
{
@@ -1966,7 +1954,8 @@ public class MetalFileChooserUI
*
* @param component the component.
*/
- public void removeLayoutComponent(Component component) {
+ public void removeLayoutComponent(Component component)
+ {
// do nothing
}
}
@@ -2072,7 +2061,8 @@ public class MetalFileChooserUI
*
* @param component the component.
*/
- public void removeLayoutComponent(Component component) {
+ public void removeLayoutComponent(Component component)
+ {
// do nothing
}
}
diff --git a/javax/swing/plaf/metal/MetalIconFactory.java b/javax/swing/plaf/metal/MetalIconFactory.java
index d24a05262..4e4c863c9 100644
--- a/javax/swing/plaf/metal/MetalIconFactory.java
+++ b/javax/swing/plaf/metal/MetalIconFactory.java
@@ -617,7 +617,8 @@ public class MetalIconFactory implements Serializable
*
* @return The width of the icon.
*/
- public int getIconWidth() {
+ public int getIconWidth()
+ {
return 16;
}
diff --git a/javax/swing/plaf/metal/MetalInternalFrameTitlePane.java b/javax/swing/plaf/metal/MetalInternalFrameTitlePane.java
index f74828e56..dd0c48639 100644
--- a/javax/swing/plaf/metal/MetalInternalFrameTitlePane.java
+++ b/javax/swing/plaf/metal/MetalInternalFrameTitlePane.java
@@ -95,7 +95,7 @@ public class MetalInternalFrameTitlePane extends BasicInternalFrameTitlePane
String propName = e.getPropertyName();
if (e.getPropertyName().equals(JInternalFrame.FRAME_ICON_PROPERTY))
{
- title.setIcon( frame.getFrameIcon() );
+ title.setIcon(frame.getFrameIcon());
}
else if (propName.equals("JInternalFrame.isPalette"))
{
@@ -387,8 +387,8 @@ public class MetalInternalFrameTitlePane extends BasicInternalFrameTitlePane
paintPalette(g);
else
{
- paintTitleBackground(g);
- paintChildren(g);
+ paintTitleBackground(g);
+ paintChildren(g);
Dimension d = getSize();
if (frame.isSelected())
g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
@@ -421,7 +421,8 @@ public class MetalInternalFrameTitlePane extends BasicInternalFrameTitlePane
endX = Math.max(closeButton.getX(), endX);
endX -= 7;
if (endX > startX)
- MetalUtils.fillMetalPattern(this, g, startX, 3, endX - startX, getHeight() - 6, Color.white, Color.gray);
+ MetalUtils.fillMetalPattern(this, g, startX, 3, endX - startX,
+ getHeight() - 6, Color.white, Color.gray);
}
g.setColor(savedColor);
}
diff --git a/javax/swing/plaf/metal/MetalLookAndFeel.java b/javax/swing/plaf/metal/MetalLookAndFeel.java
index 7a973d46e..09eafd40f 100644
--- a/javax/swing/plaf/metal/MetalLookAndFeel.java
+++ b/javax/swing/plaf/metal/MetalLookAndFeel.java
@@ -67,7 +67,7 @@ import javax.swing.plaf.basic.BasicLookAndFeel;
* }</pre>
*/
public class MetalLookAndFeel extends BasicLookAndFeel
-{
+{
private static final long serialVersionUID = 6680646159193457980L;
/** The current theme. */
@@ -888,11 +888,9 @@ public class MetalLookAndFeel extends BasicLookAndFeel
"CheckBox.font", new FontUIResource("Dialog", Font.BOLD, 12),
"CheckBox.foreground", getControlTextColor(),
"CheckBox.icon",
- new UIDefaults.ProxyLazyValue
- ("javax.swing.plaf.metal.MetalCheckBoxIcon"),
+ new UIDefaults.ProxyLazyValue("javax.swing.plaf.metal.MetalCheckBoxIcon"),
"CheckBox.checkIcon",
- new UIDefaults.ProxyLazyValue
- ("javax.swing.plaf.metal.MetalCheckBoxIcon"),
+ new UIDefaults.ProxyLazyValue("javax.swing.plaf.metal.MetalCheckBoxIcon"),
"Checkbox.select", getControlShadow(),
"CheckBoxMenuItem.acceleratorFont", new FontUIResource("Dialog", Font.PLAIN, 10),
@@ -964,7 +962,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel
"FileChooser.detailsViewIcon",
MetalIconFactory.getFileChooserDetailViewIcon(),
"FileChooser.fileNameLabelMnemonic", new Integer(78),
- "FileChooser.filesOfTypeLabelMnemonic",new Integer(84),
+ "FileChooser.filesOfTypeLabelMnemonic", new Integer(84),
"FileChooser.lookInLabelMnemonic", new Integer(73),
"FileView.computerIcon", MetalIconFactory.getTreeComputerIcon(),
"FileView.directoryIcon", MetalIconFactory.getTreeFolderIcon(),
@@ -1273,6 +1271,8 @@ public class MetalLookAndFeel extends BasicLookAndFeel
"ToolBar.light", getControlHighlight(),
"ToolBar.shadow", getControlShadow(),
"ToolBar.border", new MetalBorders.ToolBarBorder(),
+ "ToolBar.rolloverBorder", MetalBorders.getToolbarButtonBorder(),
+ "ToolBar.nonrolloverBorder", MetalBorders.getToolbarButtonBorder(),
"ToolTip.background", getPrimaryControl(),
"ToolTip.backgroundInactive", getControl(),
diff --git a/javax/swing/plaf/metal/MetalPopupMenuSeparatorUI.java b/javax/swing/plaf/metal/MetalPopupMenuSeparatorUI.java
index 44a2d3bcd..7c580f90f 100644
--- a/javax/swing/plaf/metal/MetalPopupMenuSeparatorUI.java
+++ b/javax/swing/plaf/metal/MetalPopupMenuSeparatorUI.java
@@ -51,7 +51,7 @@ public class MetalPopupMenuSeparatorUI
// FIXME: maybe replace by a Map of instances when this becomes stateful
/** The shared UI instance for MetalPopupMenuSeparatorUIs */
- private static MetalPopupMenuSeparatorUI instance = null;
+ private static MetalPopupMenuSeparatorUI instance;
/**
* Constructs a new instance of <code>MetalPopupMenuSeparatorUI</code>.
diff --git a/javax/swing/plaf/metal/MetalRadioButtonUI.java b/javax/swing/plaf/metal/MetalRadioButtonUI.java
index 9fb960f68..046e4942e 100644
--- a/javax/swing/plaf/metal/MetalRadioButtonUI.java
+++ b/javax/swing/plaf/metal/MetalRadioButtonUI.java
@@ -1,5 +1,5 @@
/* MetalRadioButtonUI.java
- Copyright (C) 2005 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -95,9 +95,10 @@ public class MetalRadioButtonUI
public void installDefaults(AbstractButton b)
{
super.installDefaults(b);
- disabledTextColor = UIManager.getColor("RadioButton.disabledText");
- focusColor = UIManager.getColor("RadioButton.focus");
- selectColor = UIManager.getColor("RadioButton.select");
+ String prefix = getPropertyPrefix();
+ disabledTextColor = UIManager.getColor(prefix + "disabledText");
+ focusColor = UIManager.getColor(prefix + "focus");
+ selectColor = UIManager.getColor(prefix + "select");
}
/**
diff --git a/javax/swing/plaf/metal/MetalRootPaneUI.java b/javax/swing/plaf/metal/MetalRootPaneUI.java
index 6cabc7e86..eaee5bf92 100644
--- a/javax/swing/plaf/metal/MetalRootPaneUI.java
+++ b/javax/swing/plaf/metal/MetalRootPaneUI.java
@@ -958,7 +958,7 @@ public class MetalRootPaneUI
/**
* The shared UI instance for MetalRootPaneUIs.
*/
- private static MetalRootPaneUI instance = null;
+ private static MetalRootPaneUI instance;
/**
* Constructs a shared instance of <code>MetalRootPaneUI</code>.
diff --git a/javax/swing/plaf/metal/MetalScrollBarUI.java b/javax/swing/plaf/metal/MetalScrollBarUI.java
index c7dfd11e4..75f2750ae 100644
--- a/javax/swing/plaf/metal/MetalScrollBarUI.java
+++ b/javax/swing/plaf/metal/MetalScrollBarUI.java
@@ -90,14 +90,14 @@ public class MetalScrollBarUI extends BasicScrollBarUI
if (e.getPropertyName().equals(FREE_STANDING_PROP))
{
Boolean prop = (Boolean) e.getNewValue();
- isFreeStanding = (prop == null ? true : prop.booleanValue());
- if (increaseButton != null)
- increaseButton.setFreeStanding(isFreeStanding);
- if (decreaseButton != null)
- decreaseButton.setFreeStanding(isFreeStanding);
+ isFreeStanding = prop == null ? true : prop.booleanValue();
+ if (increaseButton != null)
+ increaseButton.setFreeStanding(isFreeStanding);
+ if (decreaseButton != null)
+ decreaseButton.setFreeStanding(isFreeStanding);
}
else
- super.propertyChange(e);
+ super.propertyChange(e);
}
}
@@ -167,7 +167,7 @@ public class MetalScrollBarUI extends BasicScrollBarUI
// createDecreaseButton() are called (unless there is somewhere earlier
// that we can do this).
Boolean prop = (Boolean) scrollbar.getClientProperty(FREE_STANDING_PROP);
- isFreeStanding = (prop == null ? true : prop.booleanValue());
+ isFreeStanding = prop == null ? true : prop.booleanValue();
scrollBarShadowColor = UIManager.getColor("ScrollBar.shadow");
super.installDefaults();
}
@@ -401,7 +401,7 @@ public class MetalScrollBarUI extends BasicScrollBarUI
{
g.drawLine(x, y, x + w - 1, y);
g.drawLine(x, y, x, y + h - 1);
- g.drawLine(x + w - 1, y, x + w - 1, y + h -1);
+ g.drawLine(x + w - 1, y, x + w - 1, y + h - 1);
}
// then the highlight
diff --git a/javax/swing/plaf/metal/MetalSeparatorUI.java b/javax/swing/plaf/metal/MetalSeparatorUI.java
index 1d48e9be2..6d7818f8b 100644
--- a/javax/swing/plaf/metal/MetalSeparatorUI.java
+++ b/javax/swing/plaf/metal/MetalSeparatorUI.java
@@ -58,7 +58,7 @@ public class MetalSeparatorUI
// FIXME: maybe replace by a Map of instances when this becomes stateful
/** The shared UI instance for MetalSeparatorUIs */
- private static MetalSeparatorUI instance = null;
+ private static MetalSeparatorUI instance;
/**
* Constructs a new instance of <code>MetalSeparatorUI</code>.
diff --git a/javax/swing/plaf/metal/MetalSliderUI.java b/javax/swing/plaf/metal/MetalSliderUI.java
index f97717f31..0f824418c 100644
--- a/javax/swing/plaf/metal/MetalSliderUI.java
+++ b/javax/swing/plaf/metal/MetalSliderUI.java
@@ -192,10 +192,13 @@ public class MetalSliderUI extends BasicSliderUI
*/
public void paintThumb(Graphics g)
{
+ Color save = g.getColor();
+ g.setColor(thumbColor);
if (slider.getOrientation() == JSlider.HORIZONTAL)
horizThumbIcon.paintIcon(slider, g, thumbRect.x, thumbRect.y);
else
vertThumbIcon.paintIcon(slider, g, thumbRect.x, thumbRect.y);
+ g.setColor(save);
}
/**
@@ -229,9 +232,9 @@ public class MetalSliderUI extends BasicSliderUI
if (slider.isEnabled())
{
int xPos = xPositionForValue(slider.getValue());
- int x = (slider.getInverted() ? xPos : trackRect.x);
- int w = (slider.getInverted() ? trackX + trackW - xPos
- : xPos - trackRect.x);
+ int x = slider.getInverted() ? xPos : trackRect.x;
+ int w = slider.getInverted() ? trackX + trackW - xPos
+ : xPos - trackRect.x;
g.setColor(MetalLookAndFeel.getWhite());
g.drawLine(x + 1, trackY + 1, x + w - 3, trackY + 1);
g.setColor(UIManager.getColor("Slider.altTrackColor"));
@@ -245,9 +248,9 @@ public class MetalSliderUI extends BasicSliderUI
else if (filledSlider)
{
int xPos = xPositionForValue(slider.getValue());
- int x = (slider.getInverted() ? xPos : trackRect.x);
- int w = (slider.getInverted() ? trackX + trackW - xPos
- : xPos - trackRect.x);
+ int x = slider.getInverted() ? xPos : trackRect.x;
+ int w = slider.getInverted() ? trackX + trackW - xPos
+ : xPos - trackRect.x;
g.setColor(MetalLookAndFeel.getControlShadow());
g.fillRect(x + 1, trackY + 1, w - 3, getTrackWidth() - 3);
if (slider.isEnabled())
@@ -280,9 +283,9 @@ public class MetalSliderUI extends BasicSliderUI
if (slider.isEnabled())
{
int yPos = yPositionForValue(slider.getValue());
- int y = (slider.getInverted() ? trackY : yPos);
- int h = (slider.getInverted() ? yPos - trackY
- : trackY + trackH - yPos);
+ int y = slider.getInverted() ? trackY : yPos;
+ int h = slider.getInverted() ? yPos - trackY
+ : trackY + trackH - yPos;
g.setColor(MetalLookAndFeel.getWhite());
g.drawLine(trackX + 1, y + 1, trackX + 1, y + h - 3);
@@ -297,9 +300,9 @@ public class MetalSliderUI extends BasicSliderUI
else if (filledSlider)
{
int yPos = yPositionForValue(slider.getValue());
- int y = (slider.getInverted() ? trackY : yPos);
- int h = (slider.getInverted() ? yPos - trackY
- : trackY + trackH - yPos);
+ int y = slider.getInverted() ? trackY : yPos;
+ int h = slider.getInverted() ? yPos - trackY
+ : trackY + trackH - yPos;
g.setColor(MetalLookAndFeel.getControlShadow());
g.fillRect(trackX + 1, y + 1, getTrackWidth() - 3, h - 3);
if (slider.isEnabled())
@@ -323,7 +326,8 @@ public class MetalSliderUI extends BasicSliderUI
*/
public void paintFocus(Graphics g)
{
- // do nothing as focus is shown by different color on thumb control
+ thumbColor = getFocusColor();
+ paintThumb(g);
}
/**
@@ -368,8 +372,8 @@ public class MetalSliderUI extends BasicSliderUI
*/
protected int getTrackLength()
{
- return (slider.getOrientation() == JSlider.HORIZONTAL
- ? tickRect.width : tickRect.height);
+ return slider.getOrientation() == JSlider.HORIZONTAL
+ ? tickRect.width : tickRect.height;
}
/**
diff --git a/javax/swing/plaf/metal/MetalSplitPaneDivider.java b/javax/swing/plaf/metal/MetalSplitPaneDivider.java
index 9c592bd51..ba4e314f3 100644
--- a/javax/swing/plaf/metal/MetalSplitPaneDivider.java
+++ b/javax/swing/plaf/metal/MetalSplitPaneDivider.java
@@ -42,7 +42,6 @@ import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
-import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Point;
@@ -159,8 +158,8 @@ class MetalSplitPaneDivider extends BasicSplitPaneDivider
if ((c1 instanceof BasicArrowButton)
&& (c2 instanceof BasicArrowButton))
{
- lb = ((BasicArrowButton) c1);
- rb = ((BasicArrowButton) c2);
+ lb = (BasicArrowButton) c1;
+ rb = (BasicArrowButton) c2;
}
}
if (rb != null && lb != null)
diff --git a/javax/swing/plaf/metal/MetalTabbedPaneUI.java b/javax/swing/plaf/metal/MetalTabbedPaneUI.java
index 39dec3d66..c49abe832 100644
--- a/javax/swing/plaf/metal/MetalTabbedPaneUI.java
+++ b/javax/swing/plaf/metal/MetalTabbedPaneUI.java
@@ -607,11 +607,11 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI
}
else
{
- if (isOcean && tabIndex == tabPane.getSelectedIndex()+ 1)
+ if (isOcean && tabIndex == tabPane.getSelectedIndex() + 1)
{
g.setColor(oceanSelectedBorder);
}
- if (tabIndex != tabRuns[runCount- 1])
+ if (tabIndex != tabRuns[runCount - 1])
{
g.drawLine(0, 0, 0, bottom);
}
@@ -856,7 +856,7 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI
// run directly above the content or the selected tab is not visible,
// then we draw an unbroken line.
if (tabPlacement != TOP || selectedIndex < 0
- || rect.y + rect.height + 1 < y || rect.x < x ||rect.x > x + w)
+ || rect.y + rect.height + 1 < y || rect.x < x || rect.x > x + w)
{
g.drawLine(x, y, x + w - 2, y);
if (isOcean && tabPlacement == TOP)
diff --git a/javax/swing/plaf/metal/MetalToolTipUI.java b/javax/swing/plaf/metal/MetalToolTipUI.java
index f183ed5a1..d1040347f 100644
--- a/javax/swing/plaf/metal/MetalToolTipUI.java
+++ b/javax/swing/plaf/metal/MetalToolTipUI.java
@@ -75,7 +75,7 @@ public class MetalToolTipUI
public static final int padSpaceBetweenStrings = 12;
/** The shared UI instance. */
- private static MetalToolTipUI instance = null;
+ private static MetalToolTipUI instance;
/** A flag controlling the visibility of the accelerator (if there is one). */
private boolean isAcceleratorHidden;
@@ -256,8 +256,8 @@ public class MetalToolTipUI
g.setColor(acceleratorForeground);
fm = t.getFontMetrics(acceleratorFont);
int width = fm.stringWidth(acceleratorString);
- g.drawString(acceleratorString, vr.x + vr.width - width - padSpaceBetweenStrings/2,
- vr.y + vr.height - fm.getDescent());
+ g.drawString(acceleratorString, vr.x + vr.width - width
+ - padSpaceBetweenStrings / 2, vr.y + vr.height - fm.getDescent());
}
g.setColor(saved);
diff --git a/javax/swing/plaf/metal/MetalUtils.java b/javax/swing/plaf/metal/MetalUtils.java
index 03617aa40..72cbb34a6 100644
--- a/javax/swing/plaf/metal/MetalUtils.java
+++ b/javax/swing/plaf/metal/MetalUtils.java
@@ -104,7 +104,7 @@ class MetalUtils
else
g.setColor(dark);
- for (int mX = x + (xOff); mX < (x + w); mX += 4)
+ for (int mX = x + xOff; mX < (x + w); mX += 4)
{
g.drawLine(mX, mY, mX, mY);
}
diff --git a/javax/swing/plaf/multi/MultiComboBoxUI.java b/javax/swing/plaf/multi/MultiComboBoxUI.java
index 05279d7d6..33b432152 100644
--- a/javax/swing/plaf/multi/MultiComboBoxUI.java
+++ b/javax/swing/plaf/multi/MultiComboBoxUI.java
@@ -357,7 +357,8 @@ public class MultiComboBoxUI extends ComboBoxUI
* @param c the component.
* @param visible the visible state.
*/
- public void setPopupVisible(JComboBox c, boolean visible) {
+ public void setPopupVisible(JComboBox c, boolean visible)
+ {
Iterator iterator = uis.iterator();
while (iterator.hasNext())
{
@@ -376,7 +377,8 @@ public class MultiComboBoxUI extends ComboBoxUI
*
* @return The result for the UI delegate from the primary look and feel.
*/
- public boolean isPopupVisible(JComboBox c) {
+ public boolean isPopupVisible(JComboBox c)
+ {
boolean result = false;
Iterator iterator = uis.iterator();
// first UI delegate provides the return value
@@ -406,7 +408,8 @@ public class MultiComboBoxUI extends ComboBoxUI
* UI delegate in the primary look and feel, and <code>false</code>
* otherwise.
*/
- public boolean isFocusTraversable(JComboBox c) {
+ public boolean isFocusTraversable(JComboBox c)
+ {
boolean result = false;
Iterator iterator = uis.iterator();
// first UI delegate provides the return value
diff --git a/javax/swing/plaf/multi/MultiFileChooserUI.java b/javax/swing/plaf/multi/MultiFileChooserUI.java
index 6f8826010..719f04374 100644
--- a/javax/swing/plaf/multi/MultiFileChooserUI.java
+++ b/javax/swing/plaf/multi/MultiFileChooserUI.java
@@ -364,7 +364,8 @@ public class MultiFileChooserUI extends FileChooserUI
* @return The filter returned by the UI delegate from the primary
* look and feel.
*/
- public FileFilter getAcceptAllFileFilter(JFileChooser chooser) {
+ public FileFilter getAcceptAllFileFilter(JFileChooser chooser)
+ {
FileFilter result = null;
Iterator iterator = uis.iterator();
// first UI delegate provides the return value
@@ -393,7 +394,8 @@ public class MultiFileChooserUI extends FileChooserUI
* @return The view returned by the UI delegate from the primary
* look and feel.
*/
- public FileView getFileView(JFileChooser chooser) {
+ public FileView getFileView(JFileChooser chooser)
+ {
FileView result = null;
Iterator iterator = uis.iterator();
// first UI delegate provides the return value
@@ -422,7 +424,8 @@ public class MultiFileChooserUI extends FileChooserUI
* @return The text returned by the UI delegate from the primary
* look and feel.
*/
- public String getApproveButtonText(JFileChooser chooser) {
+ public String getApproveButtonText(JFileChooser chooser)
+ {
String result = null;
Iterator iterator = uis.iterator();
// first UI delegate provides the return value
@@ -451,7 +454,8 @@ public class MultiFileChooserUI extends FileChooserUI
* @return The title returned by the UI delegate from the primary
* look and feel.
*/
- public String getDialogTitle(JFileChooser chooser) {
+ public String getDialogTitle(JFileChooser chooser)
+ {
String result = null;
Iterator iterator = uis.iterator();
// first UI delegate provides the return value
@@ -476,7 +480,8 @@ public class MultiFileChooserUI extends FileChooserUI
*
* @param chooser the file chooser.
*/
- public void rescanCurrentDirectory(JFileChooser chooser) {
+ public void rescanCurrentDirectory(JFileChooser chooser)
+ {
Iterator iterator = uis.iterator();
while (iterator.hasNext())
{
@@ -493,7 +498,8 @@ public class MultiFileChooserUI extends FileChooserUI
* @param chooser the file chooser.
* @param file the file.
*/
- public void ensureFileIsVisible(JFileChooser chooser, File file) {
+ public void ensureFileIsVisible(JFileChooser chooser, File file)
+ {
Iterator iterator = uis.iterator();
while (iterator.hasNext())
{
diff --git a/javax/swing/plaf/multi/MultiListUI.java b/javax/swing/plaf/multi/MultiListUI.java
index 7350b4541..78c22419f 100644
--- a/javax/swing/plaf/multi/MultiListUI.java
+++ b/javax/swing/plaf/multi/MultiListUI.java
@@ -364,7 +364,8 @@ public class MultiListUI extends ListUI
* @return The index returned by the UI delegate from the primary
* look and feel.
*/
- public int locationToIndex(JList list, Point location) {
+ public int locationToIndex(JList list, Point location)
+ {
int result = 0;
Iterator iterator = uis.iterator();
// first UI delegate provides the return value
@@ -394,7 +395,8 @@ public class MultiListUI extends ListUI
* @return The location returned by the UI delegate from the primary
* look and feel.
*/
- public Point indexToLocation(JList list, int index) {
+ public Point indexToLocation(JList list, int index)
+ {
Point result = null;
Iterator iterator = uis.iterator();
// first UI delegate provides the return value
@@ -425,7 +427,8 @@ public class MultiListUI extends ListUI
* @return The bounds returned by the UI delegate from the primary
* look and feel.
*/
- public Rectangle getCellBounds(JList list, int index1, int index2) {
+ public Rectangle getCellBounds(JList list, int index1, int index2)
+ {
Rectangle result = null;
Iterator iterator = uis.iterator();
// first UI delegate provides the return value
diff --git a/javax/swing/plaf/multi/MultiLookAndFeel.java b/javax/swing/plaf/multi/MultiLookAndFeel.java
index 2bd358dd0..12351655a 100644
--- a/javax/swing/plaf/multi/MultiLookAndFeel.java
+++ b/javax/swing/plaf/multi/MultiLookAndFeel.java
@@ -49,7 +49,8 @@ import javax.swing.plaf.ComponentUI;
* A look and feel that provides the ability to use auxiliary look and feels
* in addition to the primary look and feel.
*/
-public class MultiLookAndFeel extends LookAndFeel {
+public class MultiLookAndFeel extends LookAndFeel
+{
/**
* Creates a new instance of the look and feel.
diff --git a/javax/swing/plaf/multi/MultiOptionPaneUI.java b/javax/swing/plaf/multi/MultiOptionPaneUI.java
index c5cb913a0..8d6f3861c 100644
--- a/javax/swing/plaf/multi/MultiOptionPaneUI.java
+++ b/javax/swing/plaf/multi/MultiOptionPaneUI.java
@@ -356,7 +356,8 @@ public class MultiOptionPaneUI extends OptionPaneUI
*
* @param pane the option pane.
*/
- public void selectInitialValue(JOptionPane pane) {
+ public void selectInitialValue(JOptionPane pane)
+ {
Iterator iterator = uis.iterator();
while (iterator.hasNext())
{
@@ -375,7 +376,8 @@ public class MultiOptionPaneUI extends OptionPaneUI
*
* @return The result for the UI delegate from the primary look and feel.
*/
- public boolean containsCustomComponents(JOptionPane pane) {
+ public boolean containsCustomComponents(JOptionPane pane)
+ {
boolean result = false;
Iterator iterator = uis.iterator();
// first UI delegate provides the return value
diff --git a/javax/swing/plaf/multi/MultiSplitPaneUI.java b/javax/swing/plaf/multi/MultiSplitPaneUI.java
index f481f8109..70ea4f13b 100644
--- a/javax/swing/plaf/multi/MultiSplitPaneUI.java
+++ b/javax/swing/plaf/multi/MultiSplitPaneUI.java
@@ -356,7 +356,8 @@ public class MultiSplitPaneUI extends SplitPaneUI
*
* @param pane the component.
*/
- public void resetToPreferredSizes(JSplitPane pane) {
+ public void resetToPreferredSizes(JSplitPane pane)
+ {
Iterator iterator = uis.iterator();
while (iterator.hasNext())
{
@@ -372,7 +373,8 @@ public class MultiSplitPaneUI extends SplitPaneUI
* @param pane the component.
* @param location the location.
*/
- public void setDividerLocation(JSplitPane pane, int location) {
+ public void setDividerLocation(JSplitPane pane, int location)
+ {
Iterator iterator = uis.iterator();
while (iterator.hasNext())
{
@@ -392,7 +394,8 @@ public class MultiSplitPaneUI extends SplitPaneUI
* @return The location returned by the UI delegate from the primary
* look and feel.
*/
- public int getDividerLocation(JSplitPane pane) {
+ public int getDividerLocation(JSplitPane pane)
+ {
int result = 0;
Iterator iterator = uis.iterator();
// first UI delegate provides the return value
@@ -421,7 +424,8 @@ public class MultiSplitPaneUI extends SplitPaneUI
* @return The location returned by the UI delegate from the primary
* look and feel.
*/
- public int getMinimumDividerLocation(JSplitPane pane) {
+ public int getMinimumDividerLocation(JSplitPane pane)
+ {
int result = 0;
Iterator iterator = uis.iterator();
// first UI delegate provides the return value
@@ -450,7 +454,8 @@ public class MultiSplitPaneUI extends SplitPaneUI
* @return The location returned by the UI delegate from the primary
* look and feel.
*/
- public int getMaximumDividerLocation(JSplitPane pane) {
+ public int getMaximumDividerLocation(JSplitPane pane)
+ {
int result = 0;
Iterator iterator = uis.iterator();
// first UI delegate provides the return value
@@ -476,7 +481,8 @@ public class MultiSplitPaneUI extends SplitPaneUI
* @param pane the component.
* @param g the graphics device.
*/
- public void finishedPaintingChildren(JSplitPane pane, Graphics g) {
+ public void finishedPaintingChildren(JSplitPane pane, Graphics g)
+ {
Iterator iterator = uis.iterator();
while (iterator.hasNext())
{
diff --git a/javax/swing/plaf/multi/MultiTabbedPaneUI.java b/javax/swing/plaf/multi/MultiTabbedPaneUI.java
index 575de192a..2a2599bde 100644
--- a/javax/swing/plaf/multi/MultiTabbedPaneUI.java
+++ b/javax/swing/plaf/multi/MultiTabbedPaneUI.java
@@ -364,7 +364,8 @@ public class MultiTabbedPaneUI extends TabbedPaneUI
* @return The tab index returned by the UI delegate from the primary
* look and feel.
*/
- public int tabForCoordinate(JTabbedPane pane, int x, int y) {
+ public int tabForCoordinate(JTabbedPane pane, int x, int y)
+ {
int result = 0;
Iterator iterator = uis.iterator();
// first UI delegate provides the return value
@@ -394,7 +395,8 @@ public class MultiTabbedPaneUI extends TabbedPaneUI
* @return The bounds returned by the UI delegate from the primary
* look and feel.
*/
- public Rectangle getTabBounds(JTabbedPane pane, int index) {
+ public Rectangle getTabBounds(JTabbedPane pane, int index)
+ {
Rectangle result = null;
Iterator iterator = uis.iterator();
// first UI delegate provides the return value
@@ -423,7 +425,8 @@ public class MultiTabbedPaneUI extends TabbedPaneUI
* @return The count returned by the UI delegate from the primary
* look and feel.
*/
- public int getTabRunCount(JTabbedPane pane) {
+ public int getTabRunCount(JTabbedPane pane)
+ {
int result = 0;
Iterator iterator = uis.iterator();
// first UI delegate provides the return value
diff --git a/javax/swing/table/AbstractTableModel.java b/javax/swing/table/AbstractTableModel.java
index 3e9f6e9b3..7914e0b3f 100644
--- a/javax/swing/table/AbstractTableModel.java
+++ b/javax/swing/table/AbstractTableModel.java
@@ -1,5 +1,5 @@
/* AbstractTableModel.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -83,7 +83,7 @@ public abstract class AbstractTableModel implements TableModel, Serializable
StringBuffer buffer = new StringBuffer();
while (columnIndex >= 0)
{
- buffer.insert (0, (char) ('A' + columnIndex % 26));
+ buffer.insert(0, (char) ('A' + columnIndex % 26));
columnIndex = columnIndex / 26 - 1;
}
return buffer.toString();
@@ -221,7 +221,7 @@ public abstract class AbstractTableModel implements TableModel, Serializable
* @param firstRow the index of the first row.
* @param lastRow the index of the last row.
*/
- public void fireTableRowsInserted (int firstRow, int lastRow)
+ public void fireTableRowsInserted(int firstRow, int lastRow)
{
fireTableChanged(new TableModelEvent(this, firstRow, lastRow,
TableModelEvent.ALL_COLUMNS,
@@ -235,7 +235,7 @@ public abstract class AbstractTableModel implements TableModel, Serializable
* @param firstRow the index of the first row.
* @param lastRow the index of the last row.
*/
- public void fireTableRowsUpdated (int firstRow, int lastRow)
+ public void fireTableRowsUpdated(int firstRow, int lastRow)
{
fireTableChanged(new TableModelEvent(this, firstRow, lastRow,
TableModelEvent.ALL_COLUMNS,
@@ -263,7 +263,7 @@ public abstract class AbstractTableModel implements TableModel, Serializable
* @param row the row index.
* @param column the column index.
*/
- public void fireTableCellUpdated (int row, int column)
+ public void fireTableCellUpdated(int row, int column)
{
fireTableChanged(new TableModelEvent(this, row, row, column));
}
@@ -282,7 +282,7 @@ public abstract class AbstractTableModel implements TableModel, Serializable
for (index = 0; index < list.length; index += 2)
{
listener = (TableModelListener) list [index + 1];
- listener.tableChanged (event);
+ listener.tableChanged(event);
}
}
diff --git a/javax/swing/table/DefaultTableModel.java b/javax/swing/table/DefaultTableModel.java
index 09be2f752..79285903c 100644
--- a/javax/swing/table/DefaultTableModel.java
+++ b/javax/swing/table/DefaultTableModel.java
@@ -1,5 +1,5 @@
/* DefaultTableModel.java --
- Copyright (C) 2002, 2004, 2005, Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -249,7 +249,7 @@ public class DefaultTableModel extends AbstractTableModel
public void setColumnIdentifiers(Vector columnIdentifiers)
{
this.columnIdentifiers = columnIdentifiers;
- setColumnCount((columnIdentifiers == null ? 0 : columnIdentifiers.size()));
+ setColumnCount(columnIdentifiers == null ? 0 : columnIdentifiers.size());
}
/**
@@ -289,13 +289,13 @@ public class DefaultTableModel extends AbstractTableModel
if (rowCount < existingRowCount)
{
dataVector.setSize(rowCount);
- fireTableRowsDeleted(rowCount,existingRowCount-1);
+ fireTableRowsDeleted(rowCount, existingRowCount - 1);
}
else
{
int rowsToAdd = rowCount - existingRowCount;
addExtraRows(rowsToAdd, columnIdentifiers.size());
- fireTableRowsInserted(existingRowCount,rowCount-1);
+ fireTableRowsInserted(existingRowCount, rowCount - 1);
}
}
@@ -353,7 +353,8 @@ public class DefaultTableModel extends AbstractTableModel
* @param columnName the column name (<code>null</code> permitted).
* @param columnData the column data.
*/
- public void addColumn(Object columnName, Object[] columnData) {
+ public void addColumn(Object columnName, Object[] columnData)
+ {
if (columnData != null)
{
// check columnData array for cases where the number of items
@@ -384,7 +385,8 @@ public class DefaultTableModel extends AbstractTableModel
*
* @param rowData the row data (<code>null</code> permitted).
*/
- public void addRow(Vector rowData) {
+ public void addRow(Vector rowData)
+ {
int rowIndex = dataVector.size();
dataVector.add(rowData);
newRowsAdded(new TableModelEvent(
@@ -398,7 +400,8 @@ public class DefaultTableModel extends AbstractTableModel
*
* @param rowData the row data (<code>null</code> permitted).
*/
- public void addRow(Object[] rowData) {
+ public void addRow(Object[] rowData)
+ {
addRow(convertToVector(rowData));
}
@@ -408,9 +411,10 @@ public class DefaultTableModel extends AbstractTableModel
* @param row the row index.
* @param rowData the row data.
*/
- public void insertRow(int row, Vector rowData) {
+ public void insertRow(int row, Vector rowData)
+ {
dataVector.add(row, rowData);
- fireTableRowsInserted(row,row);
+ fireTableRowsInserted(row, row);
}
/**
@@ -419,7 +423,8 @@ public class DefaultTableModel extends AbstractTableModel
* @param row the row index.
* @param rowData the row data.
*/
- public void insertRow(int row, Object[] rowData) {
+ public void insertRow(int row, Object[] rowData)
+ {
insertRow(row, convertToVector(rowData));
}
@@ -431,7 +436,8 @@ public class DefaultTableModel extends AbstractTableModel
* @param endIndex the end row.
* @param toIndex the row to move to.
*/
- public void moveRow(int startIndex, int endIndex, int toIndex) {
+ public void moveRow(int startIndex, int endIndex, int toIndex)
+ {
Vector removed = new Vector();
for (int i = endIndex; i >= startIndex; i--)
{
@@ -452,9 +458,10 @@ public class DefaultTableModel extends AbstractTableModel
*
* @param row the row index.
*/
- public void removeRow(int row) {
+ public void removeRow(int row)
+ {
dataVector.remove(row);
- fireTableRowsDeleted(row,row);
+ fireTableRowsDeleted(row, row);
}
/**
@@ -462,7 +469,8 @@ public class DefaultTableModel extends AbstractTableModel
*
* @return The row count.
*/
- public int getRowCount() {
+ public int getRowCount()
+ {
return dataVector.size();
}
@@ -471,8 +479,9 @@ public class DefaultTableModel extends AbstractTableModel
*
* @return The column count.
*/
- public int getColumnCount() {
- return (columnIdentifiers == null ? 0 : columnIdentifiers.size());
+ public int getColumnCount()
+ {
+ return columnIdentifiers == null ? 0 : columnIdentifiers.size();
}
/**
@@ -485,7 +494,8 @@ public class DefaultTableModel extends AbstractTableModel
*
* @return The column name.
*/
- public String getColumnName(int column) {
+ public String getColumnName(int column)
+ {
String result = "";
if (columnIdentifiers == null)
result = super.getColumnName(column);
@@ -516,7 +526,8 @@ public class DefaultTableModel extends AbstractTableModel
*
* @return <code>true</code> in all cases.
*/
- public boolean isCellEditable(int row, int column) {
+ public boolean isCellEditable(int row, int column)
+ {
return true;
}
@@ -529,7 +540,8 @@ public class DefaultTableModel extends AbstractTableModel
* @return The value (<code>Object</code>, possibly <code>null</code>) at
* the specified cell in the table.
*/
- public Object getValueAt(int row, int column) {
+ public Object getValueAt(int row, int column)
+ {
return ((Vector) dataVector.get(row)).get(column);
}
@@ -541,9 +553,10 @@ public class DefaultTableModel extends AbstractTableModel
* @param row the row index.
* @param column the column index.
*/
- public void setValueAt(Object value, int row, int column) {
+ public void setValueAt(Object value, int row, int column)
+ {
((Vector) dataVector.get(row)).set(column, value);
- fireTableCellUpdated(row,column);
+ fireTableCellUpdated(row, column);
}
/**
@@ -554,7 +567,8 @@ public class DefaultTableModel extends AbstractTableModel
* @return A vector (or <code>null</code> if the data array
* is <code>null</code>).
*/
- protected static Vector convertToVector(Object[] data) {
+ protected static Vector convertToVector(Object[] data)
+ {
if (data == null)
return null;
Vector vector = new Vector(data.length);
@@ -571,7 +585,8 @@ public class DefaultTableModel extends AbstractTableModel
* @return A vector (or <code>null</code> if the data array
* is <code>null</code>.
*/
- protected static Vector convertToVector(Object[][] data) {
+ protected static Vector convertToVector(Object[][] data)
+ {
if (data == null)
return null;
Vector vector = new Vector(data.length);
diff --git a/javax/swing/table/JTableHeader.java b/javax/swing/table/JTableHeader.java
index f7c1e1cd5..482317ff0 100644
--- a/javax/swing/table/JTableHeader.java
+++ b/javax/swing/table/JTableHeader.java
@@ -1,5 +1,5 @@
/* JTableHeader.java --
- Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,9 +38,8 @@ exception statement from your version. */
package javax.swing.table;
-import gnu.classpath.NotImplementedException;
-
import java.awt.Color;
+import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
@@ -82,282 +81,516 @@ public class JTableHeader extends JComponent
protected class AccessibleJTableHeaderEntry extends AccessibleContext
implements Accessible, AccessibleComponent
{
+
+ private int columnIndex;
+
+ private JTableHeader parent;
+
+ private JTable table;
+
public AccessibleJTableHeaderEntry(int c, JTableHeader p, JTable t)
- throws NotImplementedException
{
- throw new Error("not implemented");
+ columnIndex = c;
+ parent = p;
+ table = t;
}
+ /**
+ * Returns the column header renderer.
+ *
+ * @return The column header renderer.
+ */
+ Component getColumnHeaderRenderer()
+ {
+ TableColumn tc = parent.getColumnModel().getColumn(columnIndex);
+ TableCellRenderer r = tc.getHeaderRenderer();
+ if (r == null)
+ r = parent.getDefaultRenderer();
+ return r.getTableCellRendererComponent(table, tc.headerValue,
+ false, false, -1, columnIndex);
+ }
+
+ /**
+ * Returns the accessible context for the column header renderer, or
+ * <code>null</code>.
+ *
+ * @return The accessible context.
+ */
+ AccessibleContext getAccessibleColumnHeaderRenderer()
+ {
+ Component c = getColumnHeaderRenderer();
+ if (c instanceof Accessible)
+ return c.getAccessibleContext();
+ return null;
+ }
+
+ /**
+ * @see #removeFocusListener(FocusListener)
+ */
public void addFocusListener(FocusListener l)
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ c.addFocusListener(l);
}
+ /**
+ * @see #removePropertyChangeListener(PropertyChangeListener)
+ */
public void addPropertyChangeListener(PropertyChangeListener l)
- throws NotImplementedException
{
- throw new Error("not implemented");
+ // add the listener to the accessible context for the header
+ // renderer...
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ if (ac != null)
+ ac.addPropertyChangeListener(l);
}
public boolean contains(Point p)
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.contains(p);
+ else
+ return false;
}
public AccessibleAction getAccessibleAction()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ if (ac instanceof AccessibleAction)
+ return (AccessibleAction) ac;
+ else
+ return null;
}
public Accessible getAccessibleAt(Point p)
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.getAccessibleAt(p);
+ else
+ return null;
}
+ /**
+ * Returns <code>null</code> as the header entry has no accessible
+ * children.
+ *
+ * @return <code>null</code>.
+ */
public Accessible getAccessibleChild(int i)
- throws NotImplementedException
{
- throw new Error("not implemented");
+ return null;
}
+ /**
+ * Returns the number of accessible children, zero in this case.
+ *
+ * @return 0
+ */
public int getAccessibleChildrenCount()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ return 0;
}
+ /**
+ * Returns the accessible component for this header entry.
+ *
+ * @return <code>this</code>.
+ */
public AccessibleComponent getAccessibleComponent()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ return this;
}
+ /**
+ * Returns the accessible context for this header entry.
+ *
+ * @return <code>this</code>.
+ */
public AccessibleContext getAccessibleContext()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ return this;
}
+ /**
+ * Returns the accessible description.
+ *
+ * @return The accessible description.
+ *
+ * @see #setAccessibleDescription(String)
+ */
public String getAccessibleDescription()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ if (ac != null)
+ return ac.getAccessibleDescription();
+ return accessibleDescription;
}
+ /**
+ * Returns the index of this header entry.
+ *
+ * @return The index of this header entry.
+ */
public int getAccessibleIndexInParent()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ return columnIndex;
}
+ /**
+ * Returns the accessible name.
+ *
+ * @return The accessible name.
+ *
+ * @see #setAccessibleName(String)
+ */
public String getAccessibleName()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ if (ac != null)
+ return ac.getAccessibleName();
+ return accessibleName;
}
+ /**
+ * Returns the accessible role for the header entry.
+ *
+ * @return The accessible role.
+ */
public AccessibleRole getAccessibleRole()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ if (ac != null)
+ return ac.getAccessibleRole();
+ else
+ return null;
}
public AccessibleSelection getAccessibleSelection()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ if (ac instanceof AccessibleValue)
+ return (AccessibleSelection) ac;
+ else
+ return null;
}
public AccessibleStateSet getAccessibleStateSet()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ if (ac != null)
+ return ac.getAccessibleStateSet();
+ else
+ return null;
}
public AccessibleText getAccessibleText()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ if (ac != null)
+ return ac.getAccessibleText();
+ else
+ return null;
}
public AccessibleValue getAccessibleValue()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ if (ac instanceof AccessibleValue)
+ return (AccessibleValue) ac;
+ else
+ return null;
}
public Color getBackground()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.getBackground();
+ else
+ return null;
}
public Rectangle getBounds()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.getBounds();
+ else
+ return null;
}
public Cursor getCursor()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.getCursor();
+ else
+ return null;
}
public Font getFont()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.getFont();
+ else
+ return null;
}
public FontMetrics getFontMetrics(Font f)
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.getFontMetrics(f);
+ else
+ return null;
}
public Color getForeground()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.getForeground();
+ else
+ return null;
}
public Locale getLocale()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ Component c = getColumnHeaderRenderer();
+ if (c != null)
+ return c.getLocale();
+ return null;
}
public Point getLocation()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.getLocation();
+ else
+ return null;
}
public Point getLocationOnScreen()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.getLocationOnScreen();
+ else
+ return null;
}
public Dimension getSize()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.getSize();
+ else
+ return null;
}
public boolean isEnabled()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.isEnabled();
+ else
+ return false;
}
public boolean isFocusTraversable()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.isFocusTraversable();
+ else
+ return false;
}
public boolean isShowing()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.isShowing();
+ else
+ return false;
}
public boolean isVisible()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ return c.isVisible();
+ else
+ return false;
}
+ /**
+ * @see #addFocusListener(FocusListener)
+ */
public void removeFocusListener(FocusListener l)
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ c.removeFocusListener(l);
}
+ /**
+ * @see #addPropertyChangeListener(PropertyChangeListener)
+ */
public void removePropertyChangeListener(PropertyChangeListener l)
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ if (ac != null)
+ ac.removePropertyChangeListener(l);
}
+ /**
+ * @see #addFocusListener(FocusListener)
+ */
public void requestFocus()
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent c = ac.getAccessibleComponent();
+ if (c != null)
+ c.requestFocus();
}
+ /**
+ * @see #getAccessibleDescription()
+ */
public void setAccessibleDescription(String s)
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ if (ac != null)
+ ac.setAccessibleDescription(s);
+ else
+ accessibleDescription = s;
}
+ /**
+ * @see #getAccessibleName()
+ */
public void setAccessibleName(String s)
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ if (ac != null)
+ ac.setAccessibleName(s);
}
public void setBackground(Color c)
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent comp = ac.getAccessibleComponent();
+ if (comp != null)
+ comp.setBackground(c);
}
public void setBounds(Rectangle r)
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent comp = ac.getAccessibleComponent();
+ if (comp != null)
+ comp.setBounds(r);
}
public void setCursor(Cursor c)
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent comp = ac.getAccessibleComponent();
+ if (comp != null)
+ comp.setCursor(c);
}
public void setEnabled(boolean b)
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent comp = ac.getAccessibleComponent();
+ if (comp != null)
+ comp.setEnabled(b);
}
public void setFont(Font f)
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent comp = ac.getAccessibleComponent();
+ if (comp != null)
+ comp.setFont(f);
}
public void setForeground(Color c)
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent comp = ac.getAccessibleComponent();
+ if (comp != null)
+ comp.setForeground(c);
}
public void setLocation(Point p)
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent comp = ac.getAccessibleComponent();
+ if (comp != null)
+ comp.setLocation(p);
}
public void setSize(Dimension d)
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent comp = ac.getAccessibleComponent();
+ if (comp != null)
+ comp.setSize(d);
}
public void setVisible(boolean b)
- throws NotImplementedException
{
- throw new Error("not implemented");
+ AccessibleContext ac = getAccessibleColumnHeaderRenderer();
+ AccessibleComponent comp = ac.getAccessibleComponent();
+ if (comp != null)
+ comp.setVisible(b);
}
};
+
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.PANEL;
+ }
+
+ public int getAccessibleChildrenCount()
+ {
+ return table.getColumnCount();
+ }
+
+ public Accessible getAccessibleChild(int i)
+ {
+ return new AccessibleJTableHeaderEntry(i, JTableHeader.this, table);
+ }
+
+ public Accessible getAccessibleAt(Point p)
+ {
+ return getAccessibleChild(columnAtPoint(p));
+ }
}
/**
diff --git a/javax/swing/table/TableCellEditor.java b/javax/swing/table/TableCellEditor.java
index b355311dc..15070a755 100644
--- a/javax/swing/table/TableCellEditor.java
+++ b/javax/swing/table/TableCellEditor.java
@@ -47,19 +47,19 @@ import javax.swing.JTable;
* TableCellEditor public interface
* @author Andrew Selkirk
*/
-public interface TableCellEditor extends CellEditor {
+public interface TableCellEditor extends CellEditor
+{
- /**
- * Get table cell editor component
- * @param table JTable
- * @param value Value of cell
- * @param isSelected Cell selected
- * @param row Row of cell
- * @param column Column of cell
- * @returns Component
- */
- Component getTableCellEditorComponent(JTable table,
- Object value, boolean isSelected, int row, int column);
+ /**
+ * Get table cell editor component
+ * @param table JTable
+ * @param value Value of cell
+ * @param isSelected Cell selected
+ * @param row Row of cell
+ * @param column Column of cell
+ * @return Component
+ */
+ Component getTableCellEditorComponent(JTable table, Object value,
+ boolean isSelected, int row, int column);
-
-} // TableCellEditor
+}
diff --git a/javax/swing/table/TableCellRenderer.java b/javax/swing/table/TableCellRenderer.java
index 639b4b9ad..6c1fecf56 100644
--- a/javax/swing/table/TableCellRenderer.java
+++ b/javax/swing/table/TableCellRenderer.java
@@ -46,21 +46,21 @@ import javax.swing.JTable;
* TableCellRenderer public interface
* @author Andrew Selkirk
*/
-public interface TableCellRenderer {
+public interface TableCellRenderer
+{
- /**
- * Get table cell renderer component
- * @param table JTable
- * @param value Value of cell
- * @param isSelected Cell selected
- * @param hasFocus Cell has focus
- * @param row Row of cell
- * @param column Column of cell
- * @returns Component
- */
- Component getTableCellRendererComponent(JTable table,
- Object value, boolean isSelected, boolean hasFocus,
- int row, int column);
+ /**
+ * Get table cell renderer component
+ * @param table JTable
+ * @param value Value of cell
+ * @param isSelected Cell selected
+ * @param hasFocus Cell has focus
+ * @param row Row of cell
+ * @param column Column of cell
+ * @return Component
+ */
+ Component getTableCellRendererComponent(JTable table, Object value,
+ boolean isSelected, boolean hasFocus, int row, int column);
-} // TableCellRenderer
+}
diff --git a/javax/swing/text/AbstractDocument.java b/javax/swing/text/AbstractDocument.java
index 881b4d7f2..1ef81732f 100644
--- a/javax/swing/text/AbstractDocument.java
+++ b/javax/swing/text/AbstractDocument.java
@@ -543,6 +543,10 @@ public abstract class AbstractDocument implements Document, Serializable
*
* <p>If a {@link DocumentFilter} is installed in this document, the
* corresponding method of the filter object is called.</p>
+ *
+ * <p>The method has no effect when <code>text</code> is <code>null</code>
+ * or has a length of zero.</p>
+ *
*
* @param offset the location at which the string should be inserted
* @param text the content to be inserted
@@ -554,10 +558,14 @@ public abstract class AbstractDocument implements Document, Serializable
public void insertString(int offset, String text, AttributeSet attributes)
throws BadLocationException
{
- if (documentFilter != null)
- documentFilter.insertString(getBypass(), offset, text, attributes);
- else
+ // Bail out if we have a bogus insertion (Behavior observed in RI).
+ if (text == null || text.length() == 0)
+ return;
+
+ if (documentFilter == null)
insertStringImpl(offset, text, attributes);
+ else
+ documentFilter.insertString(getBypass(), offset, text, attributes);
}
void insertStringImpl(int offset, String text, AttributeSet attributes)
@@ -706,8 +714,14 @@ public abstract class AbstractDocument implements Document, Serializable
* Removes a piece of content from this <code>Document</code>.
*
* <p>If a {@link DocumentFilter} is installed in this document, the
- * corresponding method of the filter object is called.</p>
- *
+ * corresponding method of the filter object is called. The
+ * <code>DocumentFilter</code> is called even if <code>length</code>
+ * is zero. This is different from {@link #replace}.</p>
+ *
+ * <p>Note: When <code>length</code> is zero or below the call is not
+ * forwarded to the underlying {@link AbstractDocument.Content} instance
+ * of this document and no exception is thrown.</p>
+ *
* @param offset the start offset of the fragment to be removed
* @param length the length of the fragment to be removed
*
@@ -717,14 +731,18 @@ public abstract class AbstractDocument implements Document, Serializable
*/
public void remove(int offset, int length) throws BadLocationException
{
- if (documentFilter != null)
- documentFilter.remove(getBypass(), offset, length);
- else
+ if (documentFilter == null)
removeImpl(offset, length);
+ else
+ documentFilter.remove(getBypass(), offset, length);
}
void removeImpl(int offset, int length) throws BadLocationException
{
+ // Prevent some unneccessary method invocation (observed in the RI).
+ if (length <= 0)
+ return;
+
DefaultDocumentEvent event =
new DefaultDocumentEvent(offset, length,
DocumentEvent.EventType.REMOVE);
@@ -752,6 +770,10 @@ public abstract class AbstractDocument implements Document, Serializable
*
* <p>If a {@link DocumentFilter} is installed in this document, the
* corresponding method of the filter object is called.</p>
+ *
+ * <p>The method has no effect if <code>length</code> is zero (and
+ * only zero) and, at the same time, <code>text</code> is
+ * <code>null</code> or has zero length.</p>
*
* @param offset the start offset of the fragment to be removed
* @param length the length of the fragment to be removed
@@ -768,10 +790,25 @@ public abstract class AbstractDocument implements Document, Serializable
AttributeSet attributes)
throws BadLocationException
{
- if (documentFilter != null)
- documentFilter.replace(getBypass(), offset, length, text, attributes);
+ // Bail out if we have a bogus replacement (Behavior observed in RI).
+ if (length == 0
+ && (text == null || text.length() == 0))
+ return;
+
+ if (documentFilter == null)
+ {
+ // It is important to call the methods which again do the checks
+ // of the arguments and the DocumentFilter because subclasses may
+ // have overridden these methods and provide crucial behavior
+ // which would be skipped if we call the non-checking variants.
+ // An example for this is PlainDocument where insertString can
+ // provide a filtering of newlines.
+ remove(offset, length);
+ insertString(offset, text, attributes);
+ }
else
- replaceImpl(offset, length, text, attributes);
+ documentFilter.replace(getBypass(), offset, length, text, attributes);
+
}
void replaceImpl(int offset, int length, String text,
diff --git a/javax/swing/text/AbstractWriter.java b/javax/swing/text/AbstractWriter.java
index d5fc395e1..8d5a6075d 100644
--- a/javax/swing/text/AbstractWriter.java
+++ b/javax/swing/text/AbstractWriter.java
@@ -183,7 +183,8 @@ public abstract class AbstractWriter
if (! elt.isLeaf())
throw new BadLocationException("Element is not a leaf",
elt.getStartOffset());
- return document.getText(elt.getStartOffset(), elt.getEndOffset());
+ return document.getText(elt.getStartOffset(),
+ elt.getEndOffset() - elt.getStartOffset());
}
/**
diff --git a/javax/swing/text/DefaultCaret.java b/javax/swing/text/DefaultCaret.java
index c9369af20..4ad204c00 100644
--- a/javax/swing/text/DefaultCaret.java
+++ b/javax/swing/text/DefaultCaret.java
@@ -216,13 +216,26 @@ public class DefaultCaret extends Rectangle
*/
public void propertyChange(PropertyChangeEvent e)
{
- if (e.getPropertyName().equals("document"))
+ String name = e.getPropertyName();
+
+ if (name.equals("document"))
{
Document oldDoc = (Document) e.getOldValue();
oldDoc.removeDocumentListener(documentListener);
Document newDoc = (Document) e.getNewValue();
newDoc.addDocumentListener(documentListener);
}
+ else if (name.equals("editable"))
+ {
+ active = (((Boolean) e.getNewValue()).booleanValue()
+ && textComponent.isEnabled());
+ }
+ else if (name.equals("enabled"))
+ {
+ active = (((Boolean) e.getNewValue()).booleanValue()
+ && textComponent.isEditable());
+ }
+
}
}
@@ -281,8 +294,10 @@ public class DefaultCaret extends Rectangle
/**
* The text component in which this caret is installed.
+ *
+ * (Package private to avoid synthetic accessor method.)
*/
- private JTextComponent textComponent;
+ JTextComponent textComponent;
/**
* Indicates if the selection should be visible or not.
@@ -314,6 +329,12 @@ public class DefaultCaret extends Rectangle
* package private to avoid an accessor method.
*/
boolean visible = false;
+
+ /** Indicates whether the text component where the caret is installed is
+ * editable and enabled. If either of these properties is <code>false</code>
+ * the caret is not drawn.
+ */
+ boolean active = true;
/**
* The current highlight entry.
@@ -388,14 +409,23 @@ public class DefaultCaret extends Rectangle
/**
* Moves the caret position when the mouse is dragged over the text
- * component, modifying the selection accordingly.
+ * component, modifying the selectiony.
+ *
+ * <p>When the text component where the caret is installed is disabled,
+ * the selection is not change but you can still scroll the text and
+ * update the caret's location.</p>
*
* @param event the <code>MouseEvent</code> describing the drag operation
*/
public void mouseDragged(MouseEvent event)
{
if (event.getButton() == MouseEvent.BUTTON1)
- moveCaret(event);
+ {
+ if (textComponent.isEnabled())
+ moveCaret(event);
+ else
+ positionCaret(event);
+ }
}
/**
@@ -426,6 +456,10 @@ public class DefaultCaret extends Rectangle
*/
public void mouseClicked(MouseEvent event)
{
+ // Do not modify selection if component is disabled.
+ if (!textComponent.isEnabled())
+ return;
+
int count = event.getClickCount();
if (event.getButton() == MouseEvent.BUTTON1 && count >= 2)
@@ -523,7 +557,7 @@ public class DefaultCaret extends Rectangle
// implemented (in regard to text components):
// - a left-click moves the caret
// - a left-click when shift is held down expands the selection
- // - a right-click or click with any additionaly mouse button
+ // - a right-click or click with any additional mouse button
// on a text component is ignored
// - a middle-click positions the caret and pastes the clipboard
// contents.
@@ -540,6 +574,7 @@ public class DefaultCaret extends Rectangle
else
{
positionCaret(event);
+
textComponent.paste();
}
else
@@ -564,8 +599,11 @@ public class DefaultCaret extends Rectangle
*/
public void focusGained(FocusEvent event)
{
- setVisible(true);
- updateTimerStatus();
+ if (textComponent.isEditable())
+ {
+ setVisible(true);
+ updateTimerStatus();
+ }
}
/**
@@ -575,9 +613,10 @@ public class DefaultCaret extends Rectangle
*/
public void focusLost(FocusEvent event)
{
- if (event.isTemporary() == false)
+ if (textComponent.isEditable() && event.isTemporary() == false)
{
setVisible(false);
+
// Stop the blinker, if running.
if (blinkTimer != null && blinkTimer.isRunning())
blinkTimer.stop();
@@ -670,6 +709,7 @@ public class DefaultCaret extends Rectangle
textComponent.addPropertyChangeListener(propertyChangeListener);
documentListener = new DocumentHandler();
textComponent.getDocument().addDocumentListener(documentListener);
+ active = textComponent.isEditable() && textComponent.isEnabled();
repaint();
}
@@ -872,7 +912,7 @@ public class DefaultCaret extends Rectangle
}
// Now draw the caret on the new position if visible.
- if (visible)
+ if (visible && active)
{
g.setColor(textComponent.getCaretColor());
g.drawLine(rect.x, rect.y, rect.x, rect.y + rect.height - 1);
@@ -1013,7 +1053,9 @@ public class DefaultCaret extends Rectangle
this.dot = Math.max(this.dot, 0);
handleHighlight();
+
appear();
+
adjustVisibility(this);
}
}
@@ -1050,7 +1092,9 @@ public class DefaultCaret extends Rectangle
this.mark = this.dot;
clearHighlight();
+
appear();
+
adjustVisibility(this);
}
}
@@ -1104,7 +1148,7 @@ public class DefaultCaret extends Rectangle
*/
public boolean isVisible()
{
- return visible;
+ return visible && active;
}
/**
diff --git a/javax/swing/text/DefaultEditorKit.java b/javax/swing/text/DefaultEditorKit.java
index 1b686182b..8602e69f8 100644
--- a/javax/swing/text/DefaultEditorKit.java
+++ b/javax/swing/text/DefaultEditorKit.java
@@ -52,6 +52,7 @@ import java.io.Reader;
import java.io.Writer;
import javax.swing.Action;
+import javax.swing.SwingConstants;
/**
* The default implementation of {@link EditorKit}. This <code>EditorKit</code>
@@ -60,6 +61,7 @@ import javax.swing.Action;
*
* @author original author unknown
* @author Roman Kennke (roman@kennke.org)
+ * @author Robert Schuster (robertschuster@fsfe.org)
*/
public class DefaultEditorKit extends EditorKit
{
@@ -123,6 +125,122 @@ public class DefaultEditorKit extends EditorKit
}
}
+ static class SelectionBeginWordAction extends TextAction
+ {
+ SelectionBeginWordAction()
+ {
+ super(selectionBeginWordAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ try
+ {
+ JTextComponent t = getTextComponent(event);
+
+ if (t != null)
+ {
+ int offs = Utilities.getWordStart(t, t.getCaretPosition());
+
+ Caret c = t.getCaret();
+ c.moveDot(offs);
+ c.setMagicCaretPosition(t.modelToView(offs).getLocation());
+ }
+ }
+ catch(BadLocationException ble)
+ {
+ // Can't happen.
+ }
+ }
+ }
+
+ static class SelectionEndWordAction extends TextAction
+ {
+ SelectionEndWordAction()
+ {
+ super(selectionEndWordAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ try
+ {
+ JTextComponent t = getTextComponent(event);
+
+ if (t != null)
+ {
+ int offs = Utilities.getWordEnd(t, t.getCaretPosition());
+
+ Caret c = t.getCaret();
+ c.moveDot(offs);
+ c.setMagicCaretPosition(t.modelToView(offs).getLocation());
+ }
+ }
+ catch(BadLocationException ble)
+ {
+ // Can't happen.
+ }
+ }
+ }
+
+ static class BeginWordAction extends TextAction
+ {
+ BeginWordAction()
+ {
+ super(beginWordAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ try
+ {
+ JTextComponent t = getTextComponent(event);
+
+ if (t != null)
+ {
+ int offs = Utilities.getWordStart(t, t.getCaretPosition());
+
+ Caret c = t.getCaret();
+ c.setDot(offs);
+ c.setMagicCaretPosition(t.modelToView(offs).getLocation());
+ }
+ }
+ catch(BadLocationException ble)
+ {
+ // Can't happen.
+ }
+ }
+ }
+
+ static class EndWordAction extends TextAction
+ {
+ EndWordAction()
+ {
+ super(endWordAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ try
+ {
+ JTextComponent t = getTextComponent(event);
+
+ if (t != null)
+ {
+ int offs = Utilities.getWordEnd(t, t.getCaretPosition());
+
+ Caret c = t.getCaret();
+ c.setDot(offs);
+ c.setMagicCaretPosition(t.modelToView(offs).getLocation());
+ }
+ }
+ catch(BadLocationException ble)
+ {
+ // Can't happen.
+ }
+ }
+ }
+
static class PreviousWordAction
extends TextAction
{
@@ -258,336 +376,260 @@ public class DefaultEditorKit extends EditorKit
}
}
}
-
- static class SelectionEndLineAction
- extends TextAction
+
+ static class SelectionBeginLineAction
+ extends TextAction
{
- SelectionEndLineAction()
+
+ SelectionBeginLineAction()
{
- super(selectionEndLineAction);
+ super(selectionBeginLineAction);
}
public void actionPerformed(ActionEvent event)
{
JTextComponent t = getTextComponent(event);
- try
- {
- Point p = t.modelToView(t.getCaret().getDot()).getLocation();
- int cur = t.getCaretPosition();
- int y = p.y;
- int length = t.getDocument().getLength();
- while (y == p.y && cur < length)
- y = t.modelToView(++cur).getLocation().y;
- if (cur != length)
- cur--;
-
- Caret c = t.getCaret();
- c.moveDot(cur);
- c.setMagicCaretPosition(t.modelToView(cur).getLocation());
- }
- catch (BadLocationException ble)
- {
- // Nothing to do here
- }
+ Caret c = t.getCaret();
+ try
+ {
+ int offs = Utilities.getRowStart(t, c.getDot());
+ c.setMagicCaretPosition(t.modelToView(offs).getLocation());
+ }
+ catch(BadLocationException ble)
+ {
+ // Can't happen.
+ }
+
}
}
- static class SelectionBeginLineAction
+ static class SelectionEndLineAction
extends TextAction
{
- SelectionBeginLineAction()
+ SelectionEndLineAction()
{
- super(selectionBeginLineAction);
+ super(selectionEndLineAction);
}
public void actionPerformed(ActionEvent event)
{
JTextComponent t = getTextComponent(event);
-
+ Caret c = t.getCaret();
try
- {
- // TODO: There is a more efficent solution, but
- // viewToModel doesn't work properly.
- Point p = t.modelToView(t.getCaret().getDot()).getLocation();
-
- int cur = t.getCaretPosition();
- int y = p.y;
-
- while (y == p.y && cur > 0)
- y = t.modelToView(--cur).getLocation().y;
- if (cur != 0)
- cur++;
-
- Caret c = t.getCaret();
- c.moveDot(cur);
- c.setMagicCaretPosition(t.modelToView(cur).getLocation());
- }
- catch (BadLocationException ble)
- {
- // Do nothing here.
- }
+ {
+ int offs = Utilities.getRowEnd(t, c.getDot());
+ c.setMagicCaretPosition(t.modelToView(offs).getLocation());
+ }
+ catch(BadLocationException ble)
+ {
+ // Can't happen.
+ }
+
}
}
-
- static class SelectionDownAction
- extends TextAction
+
+ static class SelectLineAction extends TextAction
{
- SelectionDownAction()
+ SelectLineAction()
{
- super(selectionDownAction);
+ super(selectLineAction);
}
-
+
public void actionPerformed(ActionEvent event)
{
JTextComponent t = getTextComponent(event);
+ Caret c = t.getCaret();
try
{
- if (t != null)
- {
- Caret c = t.getCaret();
- // The magic caret position may be null when the caret
- // has not moved yet.
- Point mcp = c.getMagicCaretPosition();
- int x = (mcp != null) ? mcp.x : 0;
- int pos = Utilities.getPositionBelow(t, t.getCaretPosition(), x);
-
- if (pos > -1)
- t.moveCaretPosition(pos);
- }
+ int offs1 = Utilities.getRowStart(t, c.getDot());
+ int offs2 = Utilities.getRowEnd(t, c.getDot());
+
+ c.setDot(offs2);
+ c.moveDot(offs1);
+
+ c.setMagicCaretPosition(t.modelToView(offs2).getLocation());
}
- catch(BadLocationException ble)
+ catch(BadLocationException ble)
{
- // FIXME: Swallowing allowed?
+ // Can't happen.
}
}
}
-
- static class SelectionUpAction
- extends TextAction
+
+ static class SelectWordAction extends TextAction
{
- SelectionUpAction()
+ SelectWordAction()
{
- super(selectionUpAction);
+ super(selectWordAction);
}
-
+
public void actionPerformed(ActionEvent event)
{
JTextComponent t = getTextComponent(event);
+ Caret c = t.getCaret();
+ int dot = c.getDot();
+
try
{
- if (t != null)
+ int wordStart = Utilities.getWordStart(t, dot);
+
+ if (dot == wordStart)
{
- Caret c = t.getCaret();
- // The magic caret position may be null when the caret
- // has not moved yet.
- Point mcp = c.getMagicCaretPosition();
- int x = (mcp != null) ? mcp.x : 0;
- int pos = Utilities.getPositionAbove(t, t.getCaretPosition(), x);
+ // Current cursor position is on the first character in a word.
+ c.setDot(wordStart);
+ c.moveDot(Utilities.getWordEnd(t, wordStart));
+ }
+ else
+ {
+ // Current cursor position is not on the first character
+ // in a word.
+ int nextWord = Utilities.getNextWord(t, dot);
+ int previousWord = Utilities.getPreviousWord(t, dot);
+ int previousWordEnd = Utilities.getWordEnd(t, previousWord);
- if (pos > -1)
- t.moveCaretPosition(pos);
+ // Cursor position is in the space between two words. In such a
+ // situation just select the space.
+ if (dot >= previousWordEnd && dot <= nextWord)
+ {
+ c.setDot(previousWordEnd);
+ c.moveDot(nextWord);
+ }
+ else
+ {
+ // Cursor position is inside a word. Just select it then.
+ c.setDot(previousWord);
+ c.moveDot(previousWordEnd);
+ }
}
+
+ // If the position was updated change the magic caret position
+ // as well.
+ if (c.getDot() != dot)
+ c.setMagicCaretPosition(t.modelToView(c.getDot()).getLocation());
+
}
- catch(BadLocationException ble)
+ catch(BadLocationException ble)
{
- // FIXME: Swallowing allowed?
+ // Can't happen.
}
}
}
+ static class SelectionDownAction
+ extends TextAction.VerticalMovementAction
+ {
+ SelectionDownAction()
+ {
+ super(selectionDownAction, SwingConstants.SOUTH);
+ }
+
+ protected void actionPerformedImpl(Caret c, int offs)
+ {
+ c.moveDot(offs);
+ }
+
+ }
+
+ static class SelectionUpAction
+ extends TextAction.VerticalMovementAction
+ {
+ SelectionUpAction()
+ {
+ super(selectionUpAction, SwingConstants.NORTH);
+ }
+
+ protected void actionPerformedImpl(Caret c, int offs)
+ {
+ c.moveDot(offs);
+ }
+
+ }
+
static class SelectionForwardAction
- extends TextAction
+ extends TextAction.HorizontalMovementAction
{
SelectionForwardAction()
{
- super(selectionForwardAction);
+ super(selectionForwardAction, SwingConstants.EAST);
}
- public void actionPerformed(ActionEvent event)
+ protected void actionPerformedImpl(Caret c, int offs)
{
- JTextComponent t = getTextComponent(event);
- if (t != null)
- {
- int offs = t.getCaretPosition() + 1;
-
- if(offs <= t.getDocument().getLength())
- {
- Caret c = t.getCaret();
- c.moveDot(offs);
- try
- {
- c.setMagicCaretPosition(t.modelToView(offs).getLocation());
- }
- catch(BadLocationException ble)
- {
- // Can't happen.
- }
- }
- }
+ c.moveDot(offs);
}
}
static class SelectionBackwardAction
- extends TextAction
+ extends TextAction.HorizontalMovementAction
{
SelectionBackwardAction()
{
- super(selectionBackwardAction);
+ super(selectionBackwardAction, SwingConstants.WEST);
}
- public void actionPerformed(ActionEvent event)
+ protected void actionPerformedImpl(Caret c, int offs)
{
- JTextComponent t = getTextComponent(event);
- if (t != null)
- {
- int offs = t.getCaretPosition() - 1;
-
- if(offs >= 0)
- {
- Caret c = t.getCaret();
- c.moveDot(offs);
- try
- {
- c.setMagicCaretPosition(t.modelToView(offs).getLocation());
- }
- catch(BadLocationException ble)
- {
- // Can't happen.
- }
- }
- }
+ c.moveDot(offs);
}
}
static class DownAction
- extends TextAction
+ extends TextAction.VerticalMovementAction
{
DownAction()
{
- super(downAction);
+ super(downAction, SwingConstants.SOUTH);
}
- public void actionPerformed(ActionEvent event)
+ protected void actionPerformedImpl(Caret c, int offs)
{
- JTextComponent t = getTextComponent(event);
- try
- {
- if (t != null)
- {
- Caret c = t.getCaret();
- // The magic caret position may be null when the caret
- // has not moved yet.
- Point mcp = c.getMagicCaretPosition();
- int x = (mcp != null) ? mcp.x : 0;
- int pos = Utilities.getPositionBelow(t, t.getCaretPosition(), x);
-
- if (pos > -1)
- t.setCaretPosition(pos);
- }
- }
- catch(BadLocationException ble)
- {
- // FIXME: Swallowing allowed?
- }
+ c.setDot(offs);
}
}
static class UpAction
- extends TextAction
+ extends TextAction.VerticalMovementAction
{
UpAction()
{
- super(upAction);
+ super(upAction, SwingConstants.NORTH);
}
- public void actionPerformed(ActionEvent event)
+ protected void actionPerformedImpl(Caret c, int offs)
{
- JTextComponent t = getTextComponent(event);
- try
- {
- if (t != null)
- {
- Caret c = t.getCaret();
- // The magic caret position may be null when the caret
- // has not moved yet.
- Point mcp = c.getMagicCaretPosition();
- int x = (mcp != null) ? mcp.x : 0;
- int pos = Utilities.getPositionAbove(t, t.getCaretPosition(), x);
-
- if (pos > -1)
- t.setCaretPosition(pos);
- }
- }
- catch(BadLocationException ble)
- {
- // FIXME: Swallowing allowed?
- }
+ c.setDot(offs);
}
+
}
static class ForwardAction
- extends TextAction
+ extends TextAction.HorizontalMovementAction
{
ForwardAction()
{
- super(forwardAction);
+ super(forwardAction, SwingConstants.EAST);
}
- public void actionPerformed(ActionEvent event)
+ protected void actionPerformedImpl(Caret c, int offs)
{
- JTextComponent t = getTextComponent(event);
- if (t != null)
- {
- int offs = t.getCaretPosition() + 1;
- if (offs <= t.getDocument().getLength())
- {
- Caret c = t.getCaret();
- c.setDot(offs);
-
- try
- {
- c.setMagicCaretPosition(t.modelToView(offs).getLocation());
- }
- catch (BadLocationException ble)
- {
- // Should not happen.
- }
- }
- }
-
+ c.setDot(offs);
}
+
}
static class BackwardAction
- extends TextAction
+ extends TextAction.HorizontalMovementAction
{
BackwardAction()
{
- super(backwardAction);
+ super(backwardAction, SwingConstants.WEST);
}
- public void actionPerformed(ActionEvent event)
+ protected void actionPerformedImpl(Caret c, int offs)
{
- JTextComponent t = getTextComponent(event);
- if (t != null)
- {
- int offs = t.getCaretPosition() - 1;
- if (offs >= 0)
- {
- Caret c = t.getCaret();
- c.setDot(offs);
-
- try
- {
- c.setMagicCaretPosition(t.modelToView(offs).getLocation());
- }
- catch (BadLocationException ble)
- {
- // Should not happen.
- }
- }
- }
+ c.setDot(offs);
}
+
}
static class DeletePrevCharAction
@@ -720,6 +762,55 @@ public class DefaultEditorKit extends EditorKit
}
}
+ static class BeginAction extends TextAction
+ {
+
+ BeginAction()
+ {
+ super(beginAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextComponent t = getTextComponent(event);
+ Caret c = t.getCaret();
+ c.setDot(0);
+ try
+ {
+ c.setMagicCaretPosition(t.modelToView(0).getLocation());
+ }
+ catch(BadLocationException ble)
+ {
+ // Can't happen.
+ }
+ }
+ }
+
+ static class EndAction extends TextAction
+ {
+
+ EndAction()
+ {
+ super(endAction);
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextComponent t = getTextComponent(event);
+ int offs = t.getDocument().getLength();
+ Caret c = t.getCaret();
+ c.setDot(offs);
+ try
+ {
+ c.setMagicCaretPosition(t.modelToView(offs).getLocation());
+ }
+ catch(BadLocationException ble)
+ {
+ // Can't happen.
+ }
+ }
+ }
+
/**
* Creates a beep on the PC speaker.
*
@@ -867,8 +958,8 @@ public class DefaultEditorKit extends EditorKit
// first we filter the following events:
// - control characters
// - key events with the ALT modifier (FIXME: filter that too!)
- char c = event.getActionCommand().charAt(0);
- if (Character.isISOControl(c))
+ int cp = event.getActionCommand().codePointAt(0);
+ if (Character.isISOControl(cp))
return;
JTextComponent t = getTextComponent(event);
@@ -1345,8 +1436,6 @@ public class DefaultEditorKit extends EditorKit
* The <code>Action</code>s that are supported by the
* <code>DefaultEditorKit</code>.
*/
- // TODO: All these inner classes look ugly. Maybe work out a better way
- // to handle this.
private static Action[] defaultActions =
new Action[] {
// These classes are public because they are so in the RI.
@@ -1387,9 +1476,21 @@ public class DefaultEditorKit extends EditorKit
new PreviousWordAction(),
new SelectionPreviousWordAction(),
+ new BeginAction(),
new SelectionBeginAction(),
+
+ new EndAction(),
new SelectionEndAction(),
+
+ new BeginWordAction(),
+ new SelectionBeginWordAction(),
+
+ new EndWordAction(),
+ new SelectionEndWordAction(),
+
new SelectAllAction(),
+ new SelectLineAction(),
+ new SelectWordAction()
};
/**
diff --git a/javax/swing/text/FieldView.java b/javax/swing/text/FieldView.java
index 0c2f0fef1..f41f90130 100644
--- a/javax/swing/text/FieldView.java
+++ b/javax/swing/text/FieldView.java
@@ -50,6 +50,7 @@ import java.awt.event.ActionListener;
import javax.swing.BoundedRangeModel;
import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
@@ -241,12 +242,29 @@ public class FieldView extends PlainView
Shape newAlloc = adjustAllocation(s);
- // Set a clip to prevent drawing outside of the allocation area.
- // TODO: Is there a better way to achieve this?
Shape clip = g.getClip();
- g.setClip(s);
+ if (clip != null)
+ {
+ // Reason for this: The allocation area is always determined by the
+ // size of the component (and its insets) regardless of whether
+ // parts of the component are invisible or not (e.g. when the
+ // component is part of a JScrollPane and partly moved out of
+ // the user-visible range). However the clip of the Graphics
+ // instance may be adjusted properly to that condition but
+ // does not handle insets. By calculating the intersection
+ // we get the correct clip to paint the text in all cases.
+ Rectangle r = s.getBounds();
+ Rectangle cb = clip.getBounds();
+ SwingUtilities.computeIntersection(r.x, r.y, r.width, r.height, cb);
+
+ g.setClip(cb);
+ }
+ else
+ g.setClip(s);
+
super.paint(g, newAlloc);
g.setClip(clip);
+
}
public void insertUpdate(DocumentEvent ev, Shape shape, ViewFactory vf)
diff --git a/javax/swing/text/GapContent.java b/javax/swing/text/GapContent.java
index 219accb40..1780d7ddf 100644
--- a/javax/swing/text/GapContent.java
+++ b/javax/swing/text/GapContent.java
@@ -39,13 +39,10 @@ exception statement from your version. */
package javax.swing.text;
import java.io.Serializable;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
import java.util.Iterator;
-import java.util.ListIterator;
+import java.util.Set;
import java.util.Vector;
+import java.util.WeakHashMap;
import javax.swing.undo.AbstractUndoableEdit;
import javax.swing.undo.CannotRedoException;
@@ -60,8 +57,6 @@ import javax.swing.undo.UndoableEdit;
* minimal (simple array access). The array only has to be shifted around when
* the insertion point moves (then the gap also moves and one array copy is
* necessary) or when the gap is filled up and the buffer has to be enlarged.
- *
- * TODO: Implement UndoableEdit support stuff
*/
public class GapContent
implements AbstractDocument.Content, Serializable
@@ -71,11 +66,14 @@ public class GapContent
* A {@link Position} implementation for <code>GapContent</code>.
*/
private class GapContentPosition
- implements Position, Comparable
+ implements Position
{
- /** The index within the buffer array. */
- int mark;
+ /**
+ * The index to the positionMarks array entry, which in turn holds the
+ * mark into the buffer array.
+ */
+ int index;
/**
* Creates a new GapContentPosition object.
@@ -84,33 +82,20 @@ public class GapContent
*/
GapContentPosition(int mark)
{
- this.mark = mark;
- }
-
- /**
- * Comparable interface implementation. This is used to store all
- * positions in an ordered fashion.
- *
- * @param o the object to be compared to this
- *
- * @return a negative integer if this is less than <code>o</code>, zero
- * if both are equal or a positive integer if this is greater than
- * <code>o</code>
- *
- * @throws ClassCastException if <code>o</code> is not a
- * GapContentPosition or Integer object
- */
- public int compareTo(Object o)
- {
- if (o instanceof Integer)
+ // Try to find the mark in the positionMarks array, and store the index
+ // to it.
+ synchronized (GapContent.this)
{
- int otherMark = ((Integer) o).intValue();
- return mark - otherMark;
- }
- else
- {
- GapContentPosition other = (GapContentPosition) o;
- return mark - other.mark;
+ int i = binarySearch(positionMarks, mark, numMarks);
+ if (i >= 0) // mark found
+ {
+ index = i;
+ }
+ else
+ {
+ index = -i - 1;
+ insertMark(index, mark);
+ }
}
}
@@ -121,14 +106,19 @@ public class GapContent
*/
public int getOffset()
{
- // Check precondition.
- assert mark <= gapStart || mark >= gapEnd : "mark: " + mark
- + ", gapStart: " + gapStart
- + ", gapEnd: " + gapEnd;
- if (mark <= gapStart)
- return mark;
- else
- return mark - (gapEnd - gapStart);
+ synchronized (GapContent.this)
+ {
+ // Fetch the actual mark.
+ int mark = positionMarks[index];
+ // Check precondition.
+ assert mark <= gapStart || mark >= gapEnd : "mark: " + mark
+ + ", gapStart: " + gapStart
+ + ", gapEnd: " + gapEnd;
+ int res = mark;
+ if (mark > gapStart)
+ res -= (gapEnd - gapStart);
+ return res;
+ }
}
}
@@ -209,40 +199,6 @@ public class GapContent
}
- /**
- * Compares WeakReference objects in a List by comparing the referenced
- * objects instead.
- *
- * @author Roman Kennke (kennke@aicas.com)
- */
- private class WeakPositionComparator
- implements Comparator
- {
-
- /**
- * Compares two objects of type WeakReference. The objects are compared
- * using the referenced objects compareTo() method.
- */
- public int compare(Object o1, Object o2)
- {
- // Unwrap references.
- if (o1 instanceof WeakReference)
- o1 = ((WeakReference) o1).get();
- if (o2 instanceof WeakReference)
- o2 = ((WeakReference) o2).get();
-
- GapContentPosition p1 = (GapContentPosition) o1;
- GapContentPosition p2 = (GapContentPosition) o2;
-
- int retVal;
- if (p1 == null || p2 == null)
- retVal = -1;
- else
- retVal = p1.compareTo(p2);
- return retVal;
- }
- }
-
/** The serialization UID (compatible with JDK1.5). */
private static final long serialVersionUID = -6226052713477823730L;
@@ -267,12 +223,26 @@ public class GapContent
*/
int gapEnd;
+ // FIXME: We might want to track GC'ed GapContentPositions and remove their
+ // corresponding marks, or alternativly, perform some regular cleanup of
+ // the positionMarks array.
+
+ /**
+ * Holds the marks for positions. These marks are referenced by the
+ * GapContentPosition instances by an index into this array.
+ */
+ int[] positionMarks;
+
/**
- * The positions generated by this GapContent. They are kept in an ordered
- * fashion, so they can be looked up easily. The value objects will be
- * WeakReference objects that in turn hold GapContentPosition objects.
+ * The number of elements in the positionMarks array. The positionMarks array
+ * might be bigger than the actual number of elements.
*/
- private ArrayList positions;
+ int numMarks;
+
+ /**
+ * (Weakly) Stores the GapContentPosition instances.
+ */
+ WeakHashMap positions;
/**
* Creates a new GapContent object.
@@ -294,7 +264,9 @@ public class GapContent
gapStart = 1;
gapEnd = size;
buffer[0] = '\n';
- positions = new ArrayList();
+ positions = new WeakHashMap();
+ positionMarks = new int[10];
+ numMarks = 0;
}
/**
@@ -483,26 +455,30 @@ public class GapContent
*/
public Position createPosition(final int offset) throws BadLocationException
{
- if (offset < 0 || offset > length())
- throw new BadLocationException("The offset was out of the bounds of this"
- + " buffer", offset);
-
- clearPositionReferences();
-
- // We store the actual array index in the GapContentPosition. The real
- // offset is then calculated in the GapContentPosition.
- int mark = offset;
- if (offset >= gapStart)
- mark += gapEnd - gapStart;
- GapContentPosition pos = new GapContentPosition(mark);
- WeakReference r = new WeakReference(pos);
-
- // Add this into our list in a sorted fashion.
- int index = Collections.binarySearch(positions, r,
- new WeakPositionComparator());
- if (index < 0)
- index = -(index + 1);
- positions.add(index, r);
+ // We try to find a GapContentPosition at the specified offset and return
+ // that. Otherwise we must create a new one.
+ GapContentPosition pos = null;
+ Set positionSet = positions.keySet();
+ for (Iterator i = positionSet.iterator(); i.hasNext();)
+ {
+ GapContentPosition p = (GapContentPosition) i.next();
+ if (p.getOffset() == offset)
+ {
+ pos = p;
+ break;
+ }
+ }
+
+ // If none was found, then create and return a new one.
+ if (pos == null)
+ {
+ int mark = offset;
+ if (mark >= gapStart)
+ mark += (gapEnd - gapStart);
+ pos = new GapContentPosition(mark);
+ positions.put(pos, null);
+ }
+
return pos;
}
@@ -542,7 +518,6 @@ public class GapContent
{
if (newGapStart == gapStart)
return;
-
int newGapEnd = newGapStart + gapEnd - gapStart;
if (newGapStart < gapStart)
{
@@ -583,7 +558,7 @@ public class GapContent
assert newGapStart < gapStart : "The new gap start must be less than the "
+ "old gap start.";
- setPositionsInRange(newGapStart, gapStart - newGapStart, gapStart);
+ setPositionsInRange(newGapStart, gapStart, false);
gapStart = newGapStart;
}
@@ -602,7 +577,7 @@ public class GapContent
assert newGapEnd > gapEnd : "The new gap end must be greater than the "
+ "old gap end.";
- setPositionsInRange(gapEnd, newGapEnd - gapEnd, newGapEnd);
+ setPositionsInRange(gapEnd, newGapEnd, false);
gapEnd = newGapEnd;
}
@@ -688,85 +663,79 @@ public class GapContent
else
res.clear();
- int endOffset = offset + length;
-
- int index1 = Collections.binarySearch(positions,
- new GapContentPosition(offset),
- new WeakPositionComparator());
- if (index1 < 0)
- index1 = -(index1 + 1);
-
- // Search the first index with the specified offset. The binarySearch does
- // not necessarily find the first one.
- while (index1 > 0)
- {
- WeakReference r = (WeakReference) positions.get(index1 - 1);
- GapContentPosition p = (GapContentPosition) r.get();
- if (p != null && p.mark == offset || p == null)
- index1--;
- else
- break;
- }
+ int endOffs = offset + length;
- for (ListIterator i = positions.listIterator(index1); i.hasNext();)
+ Set positionSet = positions.keySet();
+ for (Iterator i = positionSet.iterator(); i.hasNext();)
{
- WeakReference r = (WeakReference) i.next();
- GapContentPosition p = (GapContentPosition) r.get();
- if (p == null)
- continue;
-
- if (p.mark > endOffset)
- break;
- if (p.mark >= offset && p.mark <= endOffset)
+ GapContentPosition p = (GapContentPosition) i.next();
+ int offs = p.getOffset();
+ if (offs >= offset && offs < endOffs)
res.add(p);
}
+
return res;
}
/**
- * Sets the mark of all <code>Position</code>s that are in the range
- * specified by <code>offset</code> and </code>length</code> within
- * the buffer array to <code>value</code>
+ * Crunches all positions in the specified range to either the start or
+ * end of that interval. The interval boundaries are meant to be inclusive
+ * [start, end].
*
- * @param offset the start offset of the range to search
- * @param length the length of the range to search
- * @param value the new value for each mark
+ * @param start the start offset of the range
+ * @param end the end offset of the range
+ * @param toStart a boolean indicating if the positions should be crunched
+ * to the start (true) or to the end (false)
*/
- private void setPositionsInRange(int offset, int length, int value)
+ private void setPositionsInRange(int start, int end, boolean toStart)
{
- int endOffset = offset + length;
-
- int index1 = Collections.binarySearch(positions,
- new GapContentPosition(offset),
- new WeakPositionComparator());
- if (index1 < 0)
- index1 = -(index1 + 1);
-
- // Search the first index with the specified offset. The binarySearch does
- // not necessarily find the first one.
- while (index1 > 0)
+ // We slump together all the GapContentPositions to point to
+ // one mark. So this is implemented as follows:
+ // 1. Remove all the marks in the specified range.
+ // 2. Insert one new mark at the correct location.
+ // 3. Adjust all affected GapContentPosition instances to point to
+ // this new mark.
+
+ synchronized (this)
{
- WeakReference r = (WeakReference) positions.get(index1 - 1);
- GapContentPosition p = (GapContentPosition) r.get();
- if (p != null && p.mark == offset || p == null)
- index1--;
+ int startIndex = binarySearch(positionMarks, start, numMarks);
+ if (startIndex < 0) // Translate to insertion index, if not found.
+ startIndex = - startIndex - 1;
+ int endIndex = binarySearch(positionMarks, end, numMarks);
+ if (endIndex < 0) // Translate to insertion index - 1, if not found.
+ endIndex = - endIndex - 2;
+
+ // Update the marks.
+ // We have inclusive interval bounds, but let one element over for
+ // filling in the new value.
+ int removed = endIndex - startIndex;
+ if (removed <= 0)
+ return;
+ System.arraycopy(positionMarks, endIndex + 1, positionMarks,
+ startIndex + 1, positionMarks.length - endIndex - 1);
+ numMarks -= removed;
+ if (toStart)
+ {
+ positionMarks[startIndex] = start;
+ }
else
- break;
- }
-
- for (ListIterator i = positions.listIterator(index1); i.hasNext();)
- {
- WeakReference r = (WeakReference) i.next();
- GapContentPosition p = (GapContentPosition) r.get();
- if (p == null)
- continue;
-
- if (p.mark > endOffset)
- break;
-
- if (p.mark >= offset && p.mark <= endOffset)
- p.mark = value;
- }
+ {
+ positionMarks[startIndex] = end;
+ }
+
+ // Update all affected GapContentPositions to point to the new index
+ // and all GapContentPositions that come after the interval to
+ // have their index moved by -removed.
+ Set positionSet = positions.keySet();
+ for (Iterator i = positionSet.iterator(); i.hasNext();)
+ {
+ GapContentPosition p = (GapContentPosition) i.next();
+ if (p.index > startIndex || p.index <= endIndex)
+ p.index = startIndex;
+ else if (p.index > endIndex)
+ p.index -= removed;
+ }
+ }
}
/**
@@ -780,39 +749,44 @@ public class GapContent
*/
private void adjustPositionsInRange(int offset, int length, int incr)
{
- int endOffset = offset + length;
+ int endMark = offset + length;
- int index1 = Collections.binarySearch(positions,
- new GapContentPosition(offset),
- new WeakPositionComparator());
- if (index1 < 0)
- index1 = -(index1 + 1);
-
- // Search the first index with the specified offset. The binarySearch does
- // not necessarily find the first one.
- while (index1 > 0)
+ synchronized (this)
{
- WeakReference r = (WeakReference) positions.get(index1 - 1);
- GapContentPosition p = (GapContentPosition) r.get();
- if (p != null && p.mark == offset || p == null)
- index1--;
- else
- break;
+ // Find the start and end indices in the positionMarks array.
+ int startIndex = binarySearch(positionMarks, offset, numMarks);
+ if (startIndex < 0) // Translate to insertion index, if not found.
+ startIndex = - startIndex - 1;
+ int endIndex = binarySearch(positionMarks, endMark, numMarks);
+ if (endIndex < 0) // Translate to insertion index - 1, if not found.
+ endIndex = - endIndex - 2;
+
+ // We must not change the order of the marks, this would have
+ // unpredictable results while binary-searching the marks.
+ assert (startIndex <= 0
+ || positionMarks[startIndex - 1]
+ <= positionMarks [startIndex] + incr)
+ && (endIndex >= numMarks - 1
+ || positionMarks[endIndex + 1]
+ >= positionMarks[endIndex] + incr)
+ : "Adjusting the marks must not change their order";
+
+ // Some debug helper output to determine if the start or end of the
+ // should ever be coalesced together with adjecent marks.
+ if (startIndex > 0 && positionMarks[startIndex - 1]
+ == positionMarks[startIndex] + incr)
+ System.err.println("DEBUG: We could coalesce the start of the region"
+ + " in GapContent.adjustPositionsInRange()");
+ if (endIndex < numMarks - 1 && positionMarks[endIndex + 1]
+ == positionMarks[endIndex] + incr)
+ System.err.println("DEBUG: We could coalesce the end of the region"
+ + " in GapContent.adjustPositionsInRange()");
+
+ // Actually adjust the marks.
+ for (int i = startIndex; i <= endIndex; i++)
+ positionMarks[i] += incr;
}
- for (ListIterator i = positions.listIterator(index1); i.hasNext();)
- {
- WeakReference r = (WeakReference) i.next();
- GapContentPosition p = (GapContentPosition) r.get();
- if (p == null)
- continue;
-
- if (p.mark > endOffset)
- break;
-
- if (p.mark >= offset && p.mark <= endOffset)
- p.mark += incr;
- }
}
/**
@@ -826,7 +800,7 @@ public class GapContent
if (gapStart != 0)
return;
- setPositionsInRange(gapEnd, 0, 0);
+ positionMarks[0] = 0;
}
/**
@@ -866,27 +840,94 @@ public class GapContent
System.err.println();
}
- private void dumpPositions()
+ /**
+ * Prints out the position marks.
+ */
+ private void dumpMarks()
+ {
+ System.err.print("positionMarks: ");
+ for (int i = 0; i < numMarks; i++)
+ System.err.print(positionMarks[i] + ", ");
+ System.err.println();
+ }
+
+ /**
+ * Inserts a mark into the positionMarks array. This must update all the
+ * GapContentPosition instances in positions that come after insertionPoint.
+ *
+ * This is package private to avoid synthetic accessor methods.
+ *
+ * @param insertionPoint the index at which to insert the mark
+ * @param mark the mark to insert
+ */
+ void insertMark(int insertionPoint, int mark)
{
- for (Iterator i = positions.iterator(); i.hasNext();)
+ synchronized (this)
{
- WeakReference r = (WeakReference) i.next();
- GapContentPosition pos = (GapContentPosition) r.get();
- System.err.println("position at: " + pos.mark);
+ // Update the positions.
+ Set positionSet = positions.keySet();
+ for (Iterator i = positionSet.iterator(); i.hasNext();)
+ {
+ GapContentPosition p = (GapContentPosition) i.next();
+ if (p.index >= insertionPoint)
+ p.index++;
+ }
+
+ // Update the position marks.
+ if (positionMarks.length <= numMarks)
+ {
+ int[] newMarks = new int[positionMarks.length + 10];
+ System.arraycopy(positionMarks, 0, newMarks, 0, insertionPoint);
+ newMarks[insertionPoint] = mark;
+ System.arraycopy(positionMarks, insertionPoint, newMarks,
+ insertionPoint + 1,
+ numMarks - insertionPoint);
+ positionMarks = newMarks;
+ }
+ else
+ {
+ System.arraycopy(positionMarks, insertionPoint, positionMarks,
+ insertionPoint + 1,
+ numMarks - insertionPoint);
+ positionMarks[insertionPoint] = mark;
+ }
+ numMarks++;
}
}
/**
- * Clears all GC'ed references in the positions array.
+ * An adaption of {@link java.util.Arrays#binarySearch(int[], int)} to
+ * specify a maximum index up to which the array is searched. This allows
+ * us to have some trailing entries that we ignore.
+ *
+ * This is package private to avoid synthetic accessor methods.
+ *
+ * @param a the array
+ * @param key the key to search for
+ * @param maxIndex the maximum index up to which the search is performed
+ *
+ * @return the index of the found entry, or (-(index)-1) for the
+ * insertion point when not found
+ *
+ * @see java.util.Arrays#binarySearch(int[], int)
*/
- private void clearPositionReferences()
+ int binarySearch(int[] a, int key, int maxIndex)
{
- Iterator i = positions.iterator();
- while (i.hasNext())
+ int low = 0;
+ int hi = maxIndex - 1;
+ int mid = 0;
+ while (low <= hi)
{
- WeakReference r = (WeakReference) i.next();
- if (r.get() == null)
- i.remove();
+ mid = (low + hi) >> 1;
+ final int d = a[mid];
+ if (d == key)
+ return mid;
+ else if (d > key)
+ hi = mid - 1;
+ else
+ // This gets the insertion point right on the last loop.
+ low = ++mid;
}
+ return -mid - 1;
}
}
diff --git a/javax/swing/text/JTextComponent.java b/javax/swing/text/JTextComponent.java
index 1103de9b4..9de151dfb 100644
--- a/javax/swing/text/JTextComponent.java
+++ b/javax/swing/text/JTextComponent.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.text;
+import gnu.classpath.NotImplementedException;
+
import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Dimension;
@@ -176,6 +178,7 @@ public abstract class JTextComponent extends JComponent
* @param e - caret event
*/
public void caretUpdate(CaretEvent e)
+ throws NotImplementedException
{
// TODO: fire appropriate event.
dot = e.getDot();
@@ -187,6 +190,7 @@ public abstract class JTextComponent extends JComponent
* @return the accessible state set of this component
*/
public AccessibleStateSet getAccessibleStateSet()
+ throws NotImplementedException
{
AccessibleStateSet state = super.getAccessibleStateSet();
// TODO: Figure out what state must be added here to the super's state.
@@ -237,6 +241,7 @@ public abstract class JTextComponent extends JComponent
* @param e - document event
*/
public void insertUpdate(DocumentEvent e)
+ throws NotImplementedException
{
// TODO
}
@@ -248,6 +253,7 @@ public abstract class JTextComponent extends JComponent
* @param e - document event
*/
public void removeUpdate(DocumentEvent e)
+ throws NotImplementedException
{
// TODO
}
@@ -259,6 +265,7 @@ public abstract class JTextComponent extends JComponent
* @param e - document event
*/
public void changedUpdate(DocumentEvent e)
+ throws NotImplementedException
{
// TODO
}
@@ -271,6 +278,7 @@ public abstract class JTextComponent extends JComponent
* @return the character index, or -1
*/
public int getIndexAtPoint(Point p)
+ throws NotImplementedException
{
return 0; // TODO
}
@@ -289,6 +297,7 @@ public abstract class JTextComponent extends JComponent
* @return the bounding box, may be empty or null.
*/
public Rectangle getCharacterBounds(int index)
+ throws NotImplementedException
{
return null; // TODO
}
@@ -311,6 +320,7 @@ public abstract class JTextComponent extends JComponent
* @return the character's attributes
*/
public AttributeSet getCharacterAttribute(int index)
+ throws NotImplementedException
{
return null; // TODO
}
@@ -324,6 +334,7 @@ public abstract class JTextComponent extends JComponent
* @return the selection of text at that index, or null
*/
public String getAtIndex(int part, int index)
+ throws NotImplementedException
{
return null; // TODO
}
@@ -337,6 +348,7 @@ public abstract class JTextComponent extends JComponent
* @return the selection of text after that index, or null
*/
public String getAfterIndex(int part, int index)
+ throws NotImplementedException
{
return null; // TODO
}
@@ -350,6 +362,7 @@ public abstract class JTextComponent extends JComponent
* @return the selection of text before that index, or null
*/
public String getBeforeIndex(int part, int index)
+ throws NotImplementedException
{
return null; // TODO
}
@@ -361,6 +374,7 @@ public abstract class JTextComponent extends JComponent
* @return the 0-based number of actions
*/
public int getAccessibleActionCount()
+ throws NotImplementedException
{
return 0; // TODO
}
@@ -369,11 +383,11 @@ public abstract class JTextComponent extends JComponent
* Get a description for the specified action. Returns null if out of
* bounds.
*
- * @param i
- * the action to describe, 0-based
+ * @param i the action to describe, 0-based
* @return description of the action
*/
public String getAccessibleActionDescription(int i)
+ throws NotImplementedException
{
// TODO: Not implemented fully
return super.getAccessibleDescription();
@@ -386,6 +400,7 @@ public abstract class JTextComponent extends JComponent
* @return true if the action was performed
*/
public boolean doAccessibleAction(int i)
+ throws NotImplementedException
{
return false; // TODO
}
@@ -396,6 +411,7 @@ public abstract class JTextComponent extends JComponent
* @param s the new text
*/
public void setTextContents(String s)
+ throws NotImplementedException
{
// TODO
}
@@ -407,6 +423,7 @@ public abstract class JTextComponent extends JComponent
* @param s the new text
*/
public void insertTextAtIndex(int index, String s)
+ throws NotImplementedException
{
replaceText(index, index, s);
}
@@ -495,6 +512,7 @@ public abstract class JTextComponent extends JComponent
* @param s the new attribute set for the range
*/
public void setAttributes(int start, int end, AttributeSet s)
+ throws NotImplementedException
{
// TODO
}
@@ -1365,7 +1383,7 @@ public abstract class JTextComponent extends JComponent
{
if (editable == newValue)
return;
-
+
boolean oldValue = editable;
editable = newValue;
firePropertyChange("editable", oldValue, newValue);
@@ -1725,17 +1743,20 @@ public abstract class JTextComponent extends JComponent
public void copy()
{
+ if (isEnabled())
doTransferAction("copy", TransferHandler.getCopyAction());
}
public void cut()
{
- doTransferAction("cut", TransferHandler.getCutAction());
+ if (editable && isEnabled())
+ doTransferAction("cut", TransferHandler.getCutAction());
}
public void paste()
{
- doTransferAction("paste", TransferHandler.getPasteAction());
+ if (editable && isEnabled())
+ doTransferAction("paste", TransferHandler.getPasteAction());
}
private void doTransferAction(String name, Action action)
diff --git a/javax/swing/text/PlainView.java b/javax/swing/text/PlainView.java
index 18818c0ba..48fe37ce8 100644
--- a/javax/swing/text/PlainView.java
+++ b/javax/swing/text/PlainView.java
@@ -437,132 +437,92 @@ public class PlainView extends View implements TabExpander
*/
protected void updateDamage(DocumentEvent changes, Shape a, ViewFactory f)
{
- // Return early and do no updates if the allocation area is null
- // (like the RI).
- if (a == null)
- return;
-
- float oldMaxLineLength = maxLineLength;
- Rectangle alloc = a.getBounds();
- Element el = getElement();
- ElementChange ec = changes.getChange(el);
-
- // If ec is null then no lines were added or removed, just
- // repaint the changed line
- if (ec == null)
- {
- int line = el.getElementIndex(changes.getOffset());
-
- // If characters have been removed from the current longest line
- // we have to find out which one is the longest now otherwise
- // the preferred x-axis span will not shrink.
- if (changes.getType() == DocumentEvent.EventType.REMOVE
- && el.getElement(line) == longestLine)
- {
- maxLineLength = -1;
- if (determineMaxLineLength() != alloc.width)
- preferenceChanged(this, true, false);
- }
-
- damageLineRange(line, line, a, getContainer());
- return;
- }
-
- Element[] removed = ec.getChildrenRemoved();
- Element[] newElements = ec.getChildrenAdded();
-
- // If no Elements were added or removed, we just want to repaint
- // the area containing the line that was modified
- if (removed == null && newElements == null)
+ // This happens during initialization.
+ if (metrics == null)
{
- int line = getElement().getElementIndex(changes.getOffset());
-
- damageLineRange(line, line, a, getContainer());
+ updateMetrics();
+ preferenceChanged(null, true, true);
return;
}
- // Check to see if we removed the longest line, if so we have to
- // search through all lines and find the longest one again.
- if (removed != null)
- {
- for (int i = 0; i < removed.length; i++)
- if (removed[i].equals(longestLine))
- {
- // reset maxLineLength and search through all lines for longest one
- maxLineLength = -1;
- if (determineMaxLineLength() != alloc.width)
- preferenceChanged(this, true, removed.length != newElements.length);
-
- ((JTextComponent)getContainer()).repaint();
-
- return;
- }
- }
-
- // If we've reached here, that means we haven't removed the longest line
- if (newElements == null)
- {
- // No lines were added, just repaint the container and exit
- ((JTextComponent)getContainer()).repaint();
-
- return;
- }
+ Element element = getElement();
- // Make sure we have the metrics
- updateMetrics();
-
- // If we've reached here, that means we haven't removed the longest line
- // and we have added at least one line, so we have to check if added lines
- // are longer than the previous longest line
- Segment seg = getLineBuffer();
- float longestNewLength = 0;
- Element longestNewLine = null;
+ // Find longest line if it hasn't been initialized yet.
+ if (longestLine == null)
+ findLongestLine(0, element.getElementCount() - 1);
- // Loop through the added lines to check their length
- for (int i = 0; i < newElements.length; i++)
+ ElementChange change = changes.getChange(element);
+ if (changes.getType() == DocumentEvent.EventType.INSERT)
{
- Element child = newElements[i];
- int start = child.getStartOffset();
- int end = child.getEndOffset() - 1;
- try
- {
- el.getDocument().getText(start, end - start, seg);
- }
- catch (BadLocationException ex)
+ // Handles character/line insertion.
+
+ // Determine if lines have been added. In this case we repaint
+ // differently.
+ boolean linesAdded = true;
+ if (change == null)
+ linesAdded = false;
+
+ // Determine the start line.
+ int start;
+ if (linesAdded)
+ start = change.getIndex();
+ else
+ start = element.getElementIndex(changes.getOffset());
+
+ // Determine the length of the updated region.
+ int length = 0;
+ if (linesAdded)
+ length = change.getChildrenAdded().length - 1;
+
+ // Update the longest line and length.
+ int oldMaxLength = (int) maxLineLength;
+ if (longestLine.getEndOffset() < changes.getOffset()
+ || longestLine.getStartOffset() > changes.getOffset()
+ + changes.getLength())
{
- AssertionError ae = new AssertionError("Unexpected bad location");
- ae.initCause(ex);
- throw ae;
+ findLongestLine(start, start + length);
}
-
- if (seg == null || seg.array == null || seg.count == 0)
- continue;
-
- int width = metrics.charsWidth(seg.array, seg.offset, seg.count);
- if (width > longestNewLength)
+ else
{
- longestNewLine = child;
- longestNewLength = width;
+ findLongestLine(0, element.getElementCount() - 1);
}
+
+ // Trigger a preference change so that the layout gets updated
+ // correctly.
+ preferenceChanged(null, maxLineLength != oldMaxLength, linesAdded);
+
+ // Damage the updated line range.
+ int endLine = start;
+ if (linesAdded)
+ endLine = element.getElementCount() - 1;
+ damageLineRange(start, endLine, a, getContainer());
+
}
-
- // Check if the longest of the new lines is longer than our previous
- // longest line, and if so update our values
- if (longestNewLength > maxLineLength)
+ else
{
- maxLineLength = longestNewLength;
- longestLine = longestNewLine;
+ // Handles character/lines removals.
+
+ // Update the longest line and length and trigger preference changed.
+ int oldMaxLength = (int) maxLineLength;
+ if (change != null)
+ {
+ // Line(s) have been removed.
+ findLongestLine(0, element.getElementCount() - 1);
+ preferenceChanged(null, maxLineLength != oldMaxLength, true);
+ }
+ else
+ {
+ // No line has been removed.
+ int lineNo = getElement().getElementIndex(changes.getOffset());
+ Element line = getElement().getElement(lineNo);
+ if (longestLine == line)
+ {
+ findLongestLine(0, element.getElementCount() - 1);
+ preferenceChanged(null, maxLineLength != oldMaxLength, false);
+ }
+ damageLineRange(lineNo, lineNo, a, getContainer());
+ }
}
-
- // Report any changes to the preferred sizes of the view
- // which may cause the underlying component to be revalidated.
- boolean widthChanged = oldMaxLineLength != maxLineLength;
- boolean heightChanged = removed.length != newElements.length;
- if (widthChanged || heightChanged)
- preferenceChanged(this, widthChanged, heightChanged);
-
- // Repaint the container
- ((JTextComponent)getContainer()).repaint();
}
/**
@@ -648,5 +608,54 @@ public class PlainView extends View implements TabExpander
lineBuffer = new Segment();
return lineBuffer;
}
+
+ /**
+ * Finds and updates the longest line in the view inside an interval of
+ * lines.
+ *
+ * @param start the start of the search interval
+ * @param end the end of the search interval
+ */
+ private void findLongestLine(int start, int end)
+ {
+ for (int i = start; i <= end; i++)
+ {
+ int w = getLineLength(i);
+ if (w > maxLineLength)
+ {
+ maxLineLength = w;
+ longestLine = getElement().getElement(i);
+ }
+ }
+ }
+
+ /**
+ * Determines the length of the specified line.
+ *
+ * @param line the number of the line
+ *
+ * @return the length of the line in pixels
+ */
+ private int getLineLength(int line)
+ {
+ Element lineEl = getElement().getElement(line);
+ Segment buffer = getLineBuffer();
+ try
+ {
+ Document doc = getDocument();
+ doc.getText(lineEl.getStartOffset(),
+ lineEl.getEndOffset() - lineEl.getStartOffset() - 1,
+ buffer);
+ }
+ catch (BadLocationException ex)
+ {
+ AssertionError err = new AssertionError("Unexpected bad location");
+ err.initCause(ex);
+ throw err;
+ }
+
+ return Utilities.getTabbedTextWidth(buffer, metrics, 0, this,
+ lineEl.getStartOffset());
+ }
}
diff --git a/javax/swing/text/StyleContext.java b/javax/swing/text/StyleContext.java
index 8ef34400d..9d09047db 100644
--- a/javax/swing/text/StyleContext.java
+++ b/javax/swing/text/StyleContext.java
@@ -413,7 +413,7 @@ public class StyleContext
/**
* These attribute keys are handled specially in serialization.
*/
- private static HashSet staticAttributeKeys = new HashSet();
+ private static Hashtable staticAttributeKeys = new Hashtable();
EventListenerList listenerList;
Hashtable styleTable;
@@ -708,44 +708,107 @@ public class StyleContext
}
}
-
- // FIXME: there's some sort of quasi-serialization stuff in here which I
- // have left incomplete; I'm not sure I understand the intent properly.
-
+ /**
+ * Gets the object previously registered with registerStaticAttributeKey.
+ *
+ * @param key - the key that was registered.
+ * @return the object previously registered with registerStaticAttributeKey.
+ */
public static Object getStaticAttribute(Object key)
- throws NotImplementedException
{
- throw new InternalError("not implemented");
+ if (key == null)
+ return null;
+ return staticAttributeKeys.get(key);
}
+ /**
+ * Returns the String that key will be registered with
+ * registerStaticAttributeKey.
+ *
+ * @param key - the key that will be registered.
+ * @return the string the key will be registered with.
+ */
public static Object getStaticAttributeKey(Object key)
- throws NotImplementedException
{
- throw new InternalError("not implemented");
+ return key.getClass().getName() + "." + key.toString();
}
+ /**
+ * Reads a set of attributes from the given object input stream. This will
+ * attempt to restore keys that were static objects by considering only the
+ * keys that have were registered with registerStaticAttributeKey. The
+ * attributes retrieved will be placed into the given set.
+ *
+ * @param in - the stream to read from
+ * @param a - the set of attributes
+ * @throws ClassNotFoundException - may be encountered when reading from
+ * stream
+ * @throws IOException - any I/O error
+ */
public static void readAttributeSet(ObjectInputStream in, MutableAttributeSet a)
- throws ClassNotFoundException, IOException, NotImplementedException
+ throws ClassNotFoundException, IOException
{
- throw new InternalError("not implemented");
+ if (in == null || a == null)
+ return;
+
+ Object key = in.readObject();
+ Object val = in.readObject();
+ while (key != null && val != null)
+ {
+ Object staticKey = staticAttributeKeys.get(key);
+ Object staticVal = staticAttributeKeys.get(val);
+
+ if (staticKey != null)
+ key = staticKey;
+ if (staticVal != null)
+ val = staticVal;
+
+ a.addAttribute(key, val);
+ key = in.readObject();
+ val = in.readObject();
+ }
}
+ /**
+ * TODO: DOCUMENT ME!
+ *
+ * @param out - stream to write to
+ * @param a - the attribute set
+ * @throws IOException - any I/O error
+ */
public static void writeAttributeSet(ObjectOutputStream out, AttributeSet a)
throws IOException, NotImplementedException
{
- throw new InternalError("not implemented");
+ // FIXME: Not implemented
}
+ /**
+ * Handles reading in the attributes.
+ * @see #readAttributeSet(ObjectInputStream, MutableAttributeSet)
+ *
+ * @param in - the stream to read from
+ * @param a - the set of attributes
+ * @throws ClassNotFoundException - may be encountered when reading from stream
+ * @throws IOException - any I/O error
+ */
public void readAttributes(ObjectInputStream in, MutableAttributeSet a)
- throws ClassNotFoundException, IOException, NotImplementedException
+ throws ClassNotFoundException, IOException
{
- throw new InternalError("not implemented");
+ readAttributeSet(in, a);
}
+ /**
+ * Handles writing of the given attributes.
+ * @see #writeAttributeSet(ObjectOutputStream, AttributeSet)
+ *
+ * @param out - stream to write to
+ * @param a - the attribute set
+ * @throws IOException - any I/O error
+ */
public void writeAttributes(ObjectOutputStream out, AttributeSet a)
- throws IOException, NotImplementedException
+ throws IOException
{
- throw new InternalError("not implemented");
+ writeAttributeSet(out, a);
}
/**
@@ -760,6 +823,8 @@ public class StyleContext
*/
public static void registerStaticAttributeKey(Object key)
{
- staticAttributeKeys.add(key);
+ if (key != null)
+ staticAttributeKeys.put(key.getClass().getName() + "." + key.toString(),
+ key);
}
}
diff --git a/javax/swing/text/TextAction.java b/javax/swing/text/TextAction.java
index 8588e3cd2..144166e9c 100644
--- a/javax/swing/text/TextAction.java
+++ b/javax/swing/text/TextAction.java
@@ -38,12 +38,14 @@ exception statement from your version. */
package javax.swing.text;
+import java.awt.Point;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.HashSet;
import javax.swing.AbstractAction;
import javax.swing.Action;
+import javax.swing.SwingConstants;
/**
* TextAction
@@ -108,4 +110,106 @@ public abstract class TextAction extends AbstractAction
{
return null; // TODO
}
+
+ /** Abstract helper class which implements everything needed for an
+ * Action implementation in <code>DefaultEditorKit</code> which
+ * does horizontal movement (and selection).
+ */
+ abstract static class HorizontalMovementAction extends TextAction
+ {
+ int dir;
+
+ HorizontalMovementAction(String name, int direction)
+ {
+ super(name);
+ dir = direction;
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextComponent t = getTextComponent(event);
+ try
+ {
+ if (t != null)
+ {
+ int offs
+ = Utilities.getNextVisualPositionFrom(t,
+ t.getCaretPosition(),
+ dir);
+
+ Caret c = t.getCaret();
+
+ actionPerformedImpl(c, offs);
+
+ c.setMagicCaretPosition(t.modelToView(offs).getLocation());
+ }
+ }
+ catch(BadLocationException ble)
+ {
+ throw
+ (InternalError) new InternalError("Illegal offset").initCause(ble);
+ }
+
+ }
+
+ protected abstract void actionPerformedImpl(Caret c, int offs)
+ throws BadLocationException;
+ }
+
+ /** Abstract helper class which implements everything needed for an
+ * Action implementation in <code>DefaultEditorKit</code> which
+ * does vertical movement (and selection).
+ */
+ abstract static class VerticalMovementAction extends TextAction
+ {
+ int dir;
+
+ VerticalMovementAction(String name, int direction)
+ {
+ super(name);
+ dir = direction;
+ }
+
+ public void actionPerformed(ActionEvent event)
+ {
+ JTextComponent t = getTextComponent(event);
+ try
+ {
+ if (t != null)
+ {
+ Caret c = t.getCaret();
+ // The magic caret position may be null when the caret
+ // has not moved yet.
+ Point mcp = c.getMagicCaretPosition();
+
+ int pos;
+ if (mcp != null)
+ {
+ mcp.y = t.modelToView(c.getDot()).y;
+ pos = t.viewToModel(mcp);
+ }
+ else
+ pos = c.getDot();
+
+ pos = Utilities.getNextVisualPositionFrom(t,
+ t.getCaretPosition(),
+ dir);
+
+ if (pos > -1)
+ actionPerformedImpl(c, pos);
+ }
+ }
+ catch(BadLocationException ble)
+ {
+ throw
+ (InternalError) new InternalError("Illegal offset").initCause(ble);
+ }
+ }
+
+ protected abstract void actionPerformedImpl(Caret c, int offs)
+ throws BadLocationException;
+
+ }
+
+
}
diff --git a/javax/swing/text/Utilities.java b/javax/swing/text/Utilities.java
index f154e55aa..36361f497 100644
--- a/javax/swing/text/Utilities.java
+++ b/javax/swing/text/Utilities.java
@@ -43,6 +43,9 @@ import java.awt.Graphics;
import java.awt.Point;
import java.text.BreakIterator;
+import javax.swing.SwingConstants;
+import javax.swing.text.Position.Bias;
+
/**
* A set of utilities to deal with text. This is used by several other classes
* inside this package.
@@ -337,7 +340,7 @@ public class Utilities
// location or is not whitespace (meaning it is a number or
// punctuation). The first case means that 'last' denotes the
// beginning of a word while the second case means it is the start
- // of some else.
+ // of something else.
if (Character.isLetter(cp)
|| !Character.isWhitespace(cp))
return last;
@@ -346,7 +349,7 @@ public class Utilities
current = wb.next();
}
- throw new BadLocationException("no more word", offs);
+ throw new BadLocationException("no more words", offs);
}
/**
@@ -363,24 +366,36 @@ public class Utilities
public static final int getPreviousWord(JTextComponent c, int offs)
throws BadLocationException
{
- if (offs < 0 || offs > (c.getText().length() - 1))
- throw new BadLocationException("invalid offset specified", offs);
String text = c.getText();
+
+ if (offs <= 0 || offs > text.length())
+ throw new BadLocationException("invalid offset specified", offs);
+
BreakIterator wb = BreakIterator.getWordInstance();
wb.setText(text);
int last = wb.preceding(offs);
int current = wb.previous();
+ int cp;
while (current != BreakIterator.DONE)
{
for (int i = last; i < offs; i++)
{
- if (Character.isLetter(text.codePointAt(i)))
+ cp = text.codePointAt(i);
+
+ // Return the last found bound if there is a letter at the current
+ // location or is not whitespace (meaning it is a number or
+ // punctuation). The first case means that 'last' denotes the
+ // beginning of a word while the second case means it is the start
+ // of some else.
+ if (Character.isLetter(cp)
+ || !Character.isWhitespace(cp))
return last;
}
last = current;
current = wb.previous();
}
+
return 0;
}
@@ -394,14 +409,17 @@ public class Utilities
public static final int getWordStart(JTextComponent c, int offs)
throws BadLocationException
{
- if (offs < 0 || offs >= c.getText().length())
+ String text = c.getText();
+
+ if (offs < 0 || offs > text.length())
throw new BadLocationException("invalid offset specified", offs);
- String text = c.getText();
BreakIterator wb = BreakIterator.getWordInstance();
wb.setText(text);
+
if (wb.isBoundary(offs))
return offs;
+
return wb.preceding(offs);
}
@@ -674,4 +692,38 @@ public class Utilities
else
return offs+1;
}
+
+ /** This is an internal helper method which is used by the
+ * <code>javax.swing.text</code> package. It simply delegates the
+ * call to a method with the same name on the <code>NavigationFilter</code>
+ * of the provided <code>JTextComponent</code> (if it has one) or its UI.
+ *
+ * If the underlying method throws a <code>BadLocationException</code> it
+ * will be swallowed and the initial offset is returned.
+ */
+ static int getNextVisualPositionFrom(JTextComponent t, int offset, int direction)
+ {
+ NavigationFilter nf = t.getNavigationFilter();
+
+ try
+ {
+ return (nf != null)
+ ? nf.getNextVisualPositionFrom(t,
+ offset,
+ Bias.Forward,
+ direction,
+ null)
+ : t.getUI().getNextVisualPositionFrom(t,
+ offset,
+ Bias.Forward,
+ direction,
+ null);
+ }
+ catch (BadLocationException ble)
+ {
+ return offset;
+ }
+
+ }
+
}
diff --git a/javax/swing/text/html/HTMLDocument.java b/javax/swing/text/html/HTMLDocument.java
index fba6cad12..4eba007f6 100644
--- a/javax/swing/text/html/HTMLDocument.java
+++ b/javax/swing/text/html/HTMLDocument.java
@@ -40,14 +40,12 @@ package javax.swing.text.html;
import gnu.classpath.NotImplementedException;
+import gnu.javax.swing.text.html.CharacterAttributeTranslator;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Stack;
import java.util.Vector;
-
-import javax.swing.event.DocumentEvent;
-import javax.swing.event.UndoableEditEvent;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
@@ -131,21 +129,6 @@ public class HTMLDocument extends DefaultStyledDocument
}
/**
- * Replaces the contents of the document with the given element
- * specifications. This is called before insert if the loading is done
- * in bursts. This is the only method called if loading the document
- * entirely in one burst.
- *
- * @param data - the date that replaces the content of the document
- */
- protected void create(DefaultStyledDocument.ElementSpec[] data)
- {
- // Once the super behaviour is properly implemented it should be sufficient
- // to simply call super.create(data).
- super.create(data);
- }
-
- /**
* This method creates a root element for the new document.
*
* @return the new default root
@@ -216,41 +199,6 @@ public class HTMLDocument extends DefaultStyledDocument
}
/**
- * Inserts new elements in bulk. This is how elements get created in the
- * document. The parsing determines what structure is needed and creates the
- * specification as a set of tokens that describe the edit while leaving the
- * document free of a write-lock. This method can then be called in bursts by
- * the reader to acquire a write-lock for a shorter duration (i.e. while the
- * document is actually being altered).
- *
- * @param offset - the starting offset
- * @param data - the element data
- * @throws BadLocationException - if the given position does not
- * represent a valid location in the associated document.
- */
- protected void insert(int offset, DefaultStyledDocument.ElementSpec[] data)
- throws BadLocationException
- {
- super.insert(offset, data);
- }
-
- /**
- * Updates document structure as a result of text insertion. This will happen
- * within a write lock. This implementation simply parses the inserted content
- * for line breaks and builds up a set of instructions for the element buffer.
- *
- * @param chng - a description of the document change
- * @param attr - the attributes
- */
- protected void insertUpdate(AbstractDocument.DefaultDocumentEvent chng,
- AttributeSet attr)
- {
- // FIXME: Not implemented
- System.out.println("insertUpdate not implemented");
- super.insertUpdate(chng, attr);
- }
-
- /**
* Returns the parser used by this HTMLDocument to insert HTML.
*
* @return the parser used by this HTMLDocument to insert HTML.
@@ -414,6 +362,7 @@ public class HTMLDocument extends DefaultStyledDocument
}
public void processHTMLFrameHyperlinkEvent(HTMLFrameHyperlinkEvent event)
+ throws NotImplementedException
{
// TODO: Implement this properly.
}
@@ -646,12 +595,16 @@ public class HTMLDocument extends DefaultStyledDocument
{
// Put the old attribute set on the stack.
pushCharacterStyle();
-
- // And create the new one by adding the attributes in <code>a</code>.
- if (a != null)
- charAttr.addAttribute(t, a.copyAttributes());
+
+ // Translate tag.. return if succesful.
+ if(CharacterAttributeTranslator.translateTag(charAttr, t, a))
+ return;
+
+ // Just add the attributes in <code>a</code>.
+ if (a != null)
+ charAttr.addAttribute(t, a.copyAttributes());
}
-
+
/**
* Called when an end tag is seen for one of the types of tags associated
* with this Action.
@@ -745,7 +698,6 @@ public class HTMLDocument extends DefaultStyledDocument
*/
public void start(HTML.Tag t, MutableAttributeSet a)
{
- // FIXME: What else must be done here?
blockOpen(t, a);
}
@@ -755,7 +707,6 @@ public class HTMLDocument extends DefaultStyledDocument
*/
public void end(HTML.Tag t)
{
- // FIXME: What else must be done here?
blockClose(t);
}
}
@@ -771,6 +722,7 @@ public class HTMLDocument extends DefaultStyledDocument
{
// FIXME: Implement.
print ("PreAction.start not implemented");
+ super.start(t, a);
}
/**
@@ -782,6 +734,7 @@ public class HTMLDocument extends DefaultStyledDocument
{
// FIXME: Implement.
print ("PreAction.end not implemented");
+ super.end(t);
}
}
@@ -1131,7 +1084,7 @@ public class HTMLDocument extends DefaultStyledDocument
*/
protected void pushCharacterStyle()
{
- charAttrStack.push(charAttr);
+ charAttrStack.push(charAttr.copyAttributes());
}
/**
@@ -1565,8 +1518,8 @@ public class HTMLDocument extends DefaultStyledDocument
*/
public Element getElement(String attrId)
{
- Element root = getDefaultRootElement();
- return getElement(root, HTML.getAttributeKey(attrId) , attrId);
+ return getElement(getDefaultRootElement(), HTML.getAttributeKey(attrId),
+ attrId);
}
/**
@@ -1690,53 +1643,4 @@ public class HTMLDocument extends DefaultStyledDocument
// FIXME: Not implemented fully, use InsertHTML* in HTMLEditorKit?
System.out.println("insertAfterStart not implemented");
}
-
- /**
- * This method sets the attributes associated with the paragraph containing
- * offset. If replace is false, s is merged with existing attributes. The
- * length argument determines how many characters are affected by the new
- * attributes. This is often the entire paragraph.
- *
- * @param offset -
- * the offset into the paragraph (must be at least 0)
- * @param length -
- * the number of characters affected (must be at least 0)
- * @param s -
- * the attributes
- * @param replace -
- * whether to replace existing attributes, or merge them
- */
- public void setParagraphAttributes(int offset, int length, AttributeSet s,
- boolean replace)
- throws NotImplementedException
- {
- // FIXME: Not implemented.
- System.out.println("setParagraphAttributes not implemented");
- super.setParagraphAttributes(offset, length, s, replace);
- }
-
- /**
- * This method flags a change in the document.
- *
- * @param e - the Document event
- */
- protected void fireChangedUpdate(DocumentEvent e)
- throws NotImplementedException
- {
- // FIXME: Not implemented.
- System.out.println("fireChangedUpdate not implemented");
- super.fireChangedUpdate(e);
- }
-
- /**
- * This method fires an event intended to be caught by Undo listeners. It
- * simply calls the super version inherited from DefaultStyledDocument. With
- * this method, an HTML editor could easily provide undo support.
- *
- * @param e - the UndoableEditEvent
- */
- protected void fireUndoableEditUpdate(UndoableEditEvent e)
- {
- super.fireUndoableEditUpdate(e);
- }
}
diff --git a/javax/swing/text/html/HTMLEditorKit.java b/javax/swing/text/html/HTMLEditorKit.java
index 92d9de938..adda4922d 100644
--- a/javax/swing/text/html/HTMLEditorKit.java
+++ b/javax/swing/text/html/HTMLEditorKit.java
@@ -548,6 +548,8 @@ public class HTMLEditorKit
|| tag.equals(HTML.Tag.BLOCKQUOTE)
|| tag.equals(HTML.Tag.PRE))
view = new BlockView(element, View.Y_AXIS);
+ else if (tag.equals(HTML.Tag.IMG))
+ view = new ImageView(element);
// FIXME: Uncomment when the views have been implemented
else if (tag.equals(HTML.Tag.CONTENT))
@@ -558,13 +560,12 @@ public class HTMLEditorKit
view = new HTMLTableView(element);
else if (tag.equals(HTML.Tag.TD))
view = new ParagraphView(element);
+
/*
else if (tag.equals(HTML.Tag.MENU) || tag.equals(HTML.Tag.DIR)
|| tag.equals(HTML.Tag.UL) || tag.equals(HTML.Tag.OL))
view = new ListView(element);
- else if (tag.equals(HTML.Tag.IMG))
- view = new ImageView(element);
else if (tag.equals(HTML.Tag.HR))
view = new HRuleView(element);
else if (tag.equals(HTML.Tag.BR))
diff --git a/javax/swing/text/html/ImageView.java b/javax/swing/text/html/ImageView.java
new file mode 100644
index 000000000..84b021070
--- /dev/null
+++ b/javax/swing/text/html/ImageView.java
@@ -0,0 +1,441 @@
+package javax.swing.text.html;
+
+import gnu.javax.swing.text.html.CombinedAttributes;
+import gnu.javax.swing.text.html.ImageViewIconFactory;
+
+import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.MediaTracker;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+import javax.swing.text.Element;
+import javax.swing.text.View;
+import javax.swing.text.Position.Bias;
+import javax.swing.text.html.HTML.Attribute;
+
+/**
+ * A view, representing a single image, represented by the HTML IMG tag.
+ *
+ * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
+ */
+public class ImageView extends View
+{
+ /**
+ * True if the image loads synchronuosly (on demand). By default, the image
+ * loads asynchronuosly.
+ */
+ boolean loadOnDemand;
+
+ /**
+ * The image icon, wrapping the image,
+ */
+ ImageIcon imageIcon;
+
+ /**
+ * The image state.
+ */
+ byte imageState = MediaTracker.LOADING;
+
+ /**
+ * Creates the image view that represents the given element.
+ *
+ * @param element the element, represented by this image view.
+ */
+ public ImageView(Element element)
+ {
+ super(element);
+ }
+
+ /**
+ * Load or reload the image. This method initiates the image reloading. After
+ * the image is ready, the repaint event will be scheduled. The current image,
+ * if it already exists, will be discarded.
+ *
+ * @param itsTime
+ * also load if the "on demand" property is set
+ */
+ void reloadImage(boolean itsTime)
+ {
+ URL url = getImageURL();
+ if (url == null)
+ imageState = (byte) MediaTracker.ERRORED;
+ else if (!(loadOnDemand && !itsTime))
+ imageIcon = new ImageIcon(url);
+ else
+ imageState = (byte) MediaTracker.LOADING;
+ }
+
+ /**
+ * Get the image alignment. This method works handling standart alignment
+ * attributes in the HTML IMG tag (align = top bottom middle left right).
+ * Depending from the parameter, either horizontal or vertical alingment
+ * information is returned.
+ *
+ * @param axis -
+ * either X_AXIS or Y_AXIS
+ */
+ public float getAlignment(int axis)
+ {
+ AttributeSet attrs = getAttributes();
+ Object al = attrs.getAttribute(Attribute.ALIGN);
+
+ // Default is top left aligned.
+ if (al == null)
+ return 0.0f;
+
+ String align = al.toString();
+
+ if (axis == View.X_AXIS)
+ {
+ if (align.equals("middle"))
+ return 0.5f;
+ else if (align.equals("left"))
+ return 0.0f;
+ else if (align.equals("right"))
+ return 1.0f;
+ else
+ return 0.0f;
+ }
+ else if (axis == View.Y_AXIS)
+ {
+ if (align.equals("middle"))
+ return 0.5f;
+ else if (align.equals("top"))
+ return 0.0f;
+ else if (align.equals("bottom"))
+ return 1.0f;
+ else
+ return 0.0f;
+ }
+ else
+ throw new IllegalArgumentException("axis " + axis);
+ }
+
+ /**
+ * Get the text that should be shown as the image replacement and also as the
+ * image tool tip text. The method returns the value of the attribute, having
+ * the name {@link Attribute#ALT}. If there is no such attribute, the image
+ * name from the url is returned. If the URL is not available, the empty
+ * string is returned.
+ */
+ public String getAltText()
+ {
+ Object rt = getAttributes().getAttribute(Attribute.ALT);
+ if (rt != null)
+ return rt.toString();
+ else
+ {
+ URL u = getImageURL();
+ if (u == null)
+ return "";
+ else
+ return u.getFile();
+ }
+ }
+
+ /**
+ * Returns the combination of the document and the style sheet attributes.
+ */
+ public AttributeSet getAttributes()
+ {
+ StyleSheet styles = getStyleSheet();
+ if (styles == null)
+ return super.getAttributes();
+ else
+ return CombinedAttributes.combine(super.getAttributes(),
+ styles.getViewAttributes(this));
+ }
+
+ /**
+ * Get the image to render. May return null if the image is not yet loaded.
+ */
+ public Image getImage()
+ {
+ if (imageIcon == null)
+ return null;
+ else
+ return imageIcon.getImage();
+ }
+
+ /**
+ * Get the URL location of the image to render. If this method returns null,
+ * the "no image" icon is rendered instead. By defaul, url must be present as
+ * the "src" property of the IMG tag. If it is missing, null is returned and
+ * the "no image" icon is rendered.
+ *
+ * @return the URL location of the image to render.
+ */
+ public URL getImageURL()
+ {
+ Object url = getAttributes().getAttribute(Attribute.SRC);
+ if (url == null)
+ return null;
+
+ try
+ {
+ return new URL(url.toString());
+ }
+ catch (MalformedURLException e)
+ {
+ // The URL is malformed - no image.
+ return null;
+ }
+ }
+
+ /**
+ * Get the icon that should be displayed while the image is loading and hence
+ * not yet available.
+ *
+ * @return an icon, showing a non broken sheet of paper with image.
+ */
+ public Icon getLoadingImageIcon()
+ {
+ return ImageViewIconFactory.getLoadingImageIcon();
+ }
+
+ /**
+ * Get the image loading strategy.
+ *
+ * @return false (default) if the image is loaded when the view is
+ * constructed, true if the image is only loaded on demand when
+ * rendering.
+ */
+ public boolean getLoadsSynchronously()
+ {
+ return loadOnDemand;
+ }
+
+ /**
+ * Get the icon that should be displayed when the image is not available.
+ *
+ * @return an icon, showing a broken sheet of paper with image.
+ */
+ public Icon getNoImageIcon()
+ {
+ return ImageViewIconFactory.getNoImageIcon();
+ }
+
+ /**
+ * Get the preferred span of the image along the axis. The image size is first
+ * requested to the attributes {@link Attribute#WIDTH} and
+ * {@link Attribute#HEIGHT}. If they are missing, and the image is already
+ * loaded, the image size is returned. If there are no attributes, and the
+ * image is not loaded, zero is returned.
+ *
+ * @param axis -
+ * either X_AXIS or Y_AXIS
+ * @return either width of height of the image, depending on the axis.
+ */
+ public float getPreferredSpan(int axis)
+ {
+ AttributeSet attrs = getAttributes();
+
+ Image image = getImage();
+
+ if (axis == View.X_AXIS)
+ {
+ Object w = attrs.getAttribute(Attribute.WIDTH);
+ if (w != null)
+ return Integer.parseInt(w.toString());
+ else if (image != null)
+ return image.getWidth(getContainer());
+ else
+ return getNoImageIcon().getIconWidth();
+ }
+ else if (axis == View.Y_AXIS)
+ {
+ Object w = attrs.getAttribute(Attribute.HEIGHT);
+ if (w != null)
+ return Integer.parseInt(w.toString());
+ else if (image != null)
+ return image.getHeight(getContainer());
+ else
+ return getNoImageIcon().getIconHeight();
+ }
+ else
+ throw new IllegalArgumentException("axis " + axis);
+ }
+
+ /**
+ * Get the associated style sheet from the document.
+ *
+ * @return the associated style sheet.
+ */
+ protected StyleSheet getStyleSheet()
+ {
+ Document d = getElement().getDocument();
+ if (d instanceof HTMLDocument)
+ return ((HTMLDocument) d).getStyleSheet();
+ else
+ return null;
+ }
+
+ /**
+ * Get the tool tip text. This is overridden to return the value of the
+ * {@link #getAltText()}. The parameters are ignored.
+ *
+ * @return that is returned by getAltText().
+ */
+ public String getToolTipText(float x, float y, Shape shape)
+ {
+ return getAltText();
+ }
+
+ /**
+ * Paints the image or one of the two image state icons. The image is resized
+ * to the shape bounds. If there is no image available, the alternative text
+ * is displayed besides the image state icon.
+ *
+ * @param g
+ * the Graphics, used for painting.
+ * @param bounds
+ * the bounds of the region where the image or replacing icon must be
+ * painted.
+ */
+ public void paint(Graphics g, Shape bounds)
+ {
+ Rectangle r = bounds.getBounds();
+
+ if (imageIcon == null)
+
+ {
+ // Loading image on demand, rendering the loading icon so far.
+ reloadImage(true);
+
+ // The reloadImage sets the imageIcon, unless the URL is broken
+ // or malformed.
+ if (imageIcon != null)
+ {
+ if (imageIcon.getImageLoadStatus() != MediaTracker.COMPLETE)
+ {
+ // Render "not ready" icon, unless the image is ready
+ // immediately.
+ renderIcon(g, r, getLoadingImageIcon());
+ // Add the listener to repaint when the icon will be ready.
+ imageIcon.setImageObserver(getContainer());
+ return;
+ }
+ }
+ else
+ {
+ renderIcon(g, r, getNoImageIcon());
+ return;
+ }
+ }
+
+ imageState = (byte) imageIcon.getImageLoadStatus();
+
+ switch (imageState)
+ {
+ case MediaTracker.ABORTED:
+ case MediaTracker.ERRORED:
+ renderIcon(g, r, getNoImageIcon());
+ break;
+ case MediaTracker.LOADING:
+ // If the image is not loaded completely, we still render it, as the
+ // partial image may be available.
+ case MediaTracker.COMPLETE:
+ {
+ // Paint the scaled image.
+ Image scaled = imageIcon.getImage().getScaledInstance(
+ r.width,
+ r.height,
+ Image.SCALE_DEFAULT);
+ ImageIcon painter = new ImageIcon(scaled);
+ painter.paintIcon(getContainer(), g, r.x, r.y);
+ }
+ break;
+ }
+ }
+
+ /**
+ * Render "no image" icon and the alternative "no image" text. The text is
+ * rendered right from the icon and is aligned to the icon bottom.
+ */
+ private void renderIcon(Graphics g, Rectangle bounds, Icon icon)
+ {
+ Shape current = g.getClip();
+ try
+ {
+ g.setClip(bounds);
+ if (icon != null)
+ {
+ icon.paintIcon(getContainer(), g, bounds.x, bounds.y);
+ g.drawString(getAltText(), bounds.x + icon.getIconWidth(),
+ bounds.y + icon.getIconHeight());
+ }
+ }
+ finally
+ {
+ g.setClip(current);
+ }
+ }
+
+ /**
+ * Set if the image should be loaded only when needed (synchronuosly). By
+ * default, the image loads asynchronuosly. If the image is not yet ready, the
+ * icon, returned by the {@link #getLoadingImageIcon()}, is displayed.
+ */
+ public void setLoadsSynchronously(boolean load_on_demand)
+ {
+ loadOnDemand = load_on_demand;
+ }
+
+ /**
+ * Update all cached properties from the attribute set, returned by the
+ * {@link #getAttributes}.
+ */
+ protected void setPropertiesFromAttributes()
+ {
+ // In the current implementation, nothing is cached yet, unless the image
+ // itself.
+ imageIcon = null;
+ }
+
+ /**
+ * Maps the picture co-ordinates into the image position in the model. As the
+ * image is not divideable, this is currently implemented always to return the
+ * start offset.
+ */
+ public int viewToModel(float x, float y, Shape shape, Bias[] bias)
+ {
+ return getStartOffset();
+ }
+
+ /**
+ * This is currently implemented always to return the area of the image view,
+ * as the image is not divideable by character positions.
+ *
+ * @param pos character position
+ * @param area of the image view
+ * @param bias bias
+ *
+ * @return the shape, where the given character position should be mapped.
+ */
+ public Shape modelToView(int pos, Shape area, Bias bias)
+ throws BadLocationException
+ {
+ return area;
+ }
+
+ /**
+ * Starts loading the image asynchronuosly. If the image must be loaded
+ * synchronuosly instead, the {@link #setLoadsSynchronously} must be
+ * called before calling this method. The passed parameters are not used.
+ */
+ public void setSize(float width, float height)
+ {
+ if (imageIcon == null)
+ reloadImage(false);
+ }
+
+
+}
diff --git a/javax/swing/text/html/MinimalHTMLWriter.java b/javax/swing/text/html/MinimalHTMLWriter.java
new file mode 100644
index 000000000..d42951a05
--- /dev/null
+++ b/javax/swing/text/html/MinimalHTMLWriter.java
@@ -0,0 +1,452 @@
+/* MinimalHTMLWriter.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 javax.swing.text.html;
+
+import javax.swing.text.AttributeSet;
+import javax.swing.text.AbstractWriter;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.DefaultStyledDocument;
+import javax.swing.text.Element;
+import javax.swing.text.ElementIterator;
+import javax.swing.text.StyleConstants;
+import javax.swing.text.Style;
+import javax.swing.text.StyledDocument;
+import java.io.Writer;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Stack;
+import java.awt.Color;
+
+/**
+ * MinimalHTMLWriter,
+ * A minimal AbstractWriter implementation for HTML.
+ *
+ * @author Sven de Marothy
+ */
+public class MinimalHTMLWriter extends AbstractWriter
+{
+ private StyledDocument doc;
+ private Stack tagStack;
+ private boolean inFontTag = false;
+
+ /**
+ * Constructs a MinimalHTMLWriter.
+ * @param w - a Writer, for output.
+ * @param doc - the document
+ */
+ public MinimalHTMLWriter(Writer w, StyledDocument doc)
+ {
+ super(w, doc);
+ this.doc = doc;
+ tagStack = new Stack();
+ }
+
+ /**
+ * Constructs a MinimalHTMLWriter.
+ * @param w - a Writer, for output.
+ * @param doc - the document
+ * @param pos - start position
+ * @param len - length
+ */
+ public MinimalHTMLWriter(Writer w, StyledDocument doc, int pos, int len)
+ {
+ super(w, doc, pos, len);
+ this.doc = doc;
+ tagStack = new Stack();
+ }
+
+ /**
+ * Starts a span tag.
+ */
+ protected void startFontTag(String style) throws IOException
+ {
+ if( inFontTag() )
+ endOpenTags();
+ writeStartTag("<span style=\""+style+"\">");
+ inFontTag = true;
+ }
+
+ /**
+ * Returns whether the writer is within two span tags.
+ */
+ protected boolean inFontTag()
+ {
+ return inFontTag;
+ }
+
+ /**
+ * Ends a span tag.
+ */
+ protected void endFontTag() throws IOException
+ {
+ writeEndTag("</span>");
+ inFontTag = false;
+ }
+
+ /**
+ * Write the entire HTML document.
+ */
+ public synchronized void write() throws IOException, BadLocationException
+ {
+ writeStartTag("<html>");
+ writeHeader();
+ writeBody();
+ writeEndTag("</html>");
+ }
+
+ /**
+ * Write a start tag and increment the indent.
+ */
+ protected void writeStartTag(String tag) throws IOException
+ {
+ indent();
+ write(tag+NEWLINE);
+ incrIndent();
+ }
+
+ /**
+ * Write an ending tag and decrement the indent.
+ */
+ protected void writeEndTag(String endTag) throws IOException
+ {
+ decrIndent();
+ indent();
+ write(endTag+NEWLINE);
+ }
+
+ /**
+ * Write the HTML header.
+ */
+ protected void writeHeader() throws IOException
+ {
+ writeStartTag("<head>");
+ writeStartTag("<style>");
+ writeStartTag("<!--");
+ writeStyles();
+ writeEndTag("-->");
+ writeEndTag("</style>");
+ writeEndTag("</head>");
+ }
+
+ /**
+ * Write a paragraph start tag.
+ */
+ protected void writeStartParagraph(Element elem) throws IOException
+ {
+ indent();
+ write("<p class=default>"+NEWLINE); // FIXME: Class value = ?
+ incrIndent();
+ }
+
+ /**
+ * Write a paragraph end tag, closes any other open tags.
+ */
+ protected void writeEndParagraph() throws IOException
+ {
+ endOpenTags();
+ writeEndTag("</p>");
+ }
+
+ /**
+ * Writes the body of the HTML document.
+ */
+ protected void writeBody() throws IOException, BadLocationException
+ {
+ writeStartTag("<body>");
+
+ ElementIterator ei = getElementIterator();
+ Element e = ei.first();
+ boolean inParagraph = false;
+ do
+ {
+ if( e.isLeaf() )
+ {
+ boolean hasNL = (getText(e).indexOf(NEWLINE) != -1);
+ if( !inParagraph && hasText( e ) )
+ {
+ writeStartParagraph(e);
+ inParagraph = true;
+ }
+
+ if( hasText( e ) )
+ writeContent(e, true);
+
+ if( hasNL && inParagraph )
+ {
+ writeEndParagraph();
+ inParagraph = false;
+ }
+ else
+ endOpenTags();
+ }
+ }
+ while((e = ei.next()) != null);
+
+ writeEndTag("</body>");
+ }
+
+ protected void text(Element elem) throws IOException, BadLocationException
+ {
+ write( getText(elem).trim() );
+ }
+
+ /**
+ * Write bold, indent and underline tags.
+ */
+ protected void writeHTMLTags(AttributeSet attr) throws IOException
+ {
+ if(attr.getAttribute(StyleConstants.Bold) != null)
+ if(((Boolean)attr.getAttribute(StyleConstants.Bold)).booleanValue())
+ {
+ write("<b>");
+ tagStack.push("</b>");
+ }
+ if(attr.getAttribute(StyleConstants.Italic) != null)
+ if(((Boolean)attr.getAttribute(StyleConstants.Italic)).booleanValue())
+ {
+ write("<i>");
+ tagStack.push("</i>");
+ }
+ if(attr.getAttribute(StyleConstants.Underline) != null)
+ if(((Boolean)attr.getAttribute(StyleConstants.Underline)).booleanValue())
+ {
+ write("<u>");
+ tagStack.push("</u>");
+ }
+ }
+
+ /**
+ * Returns whether the element contains text or not.
+ */
+ protected boolean isText(Element elem)
+ {
+ return (elem.getEndOffset() != elem.getStartOffset());
+ }
+
+ /**
+ * Writes the content of an element.
+ */
+ protected void writeContent(Element elem, boolean needsIndenting)
+ throws IOException, BadLocationException
+ {
+ writeNonHTMLAttributes(elem.getAttributes());
+ if(needsIndenting)
+ indent();
+ writeHTMLTags(elem.getAttributes());
+ if( isText(elem) )
+ text(elem);
+ else
+ writeLeaf(elem);
+
+ endOpenTags();
+ }
+
+ /**
+ * Writes a non-text leaf element.
+ */
+ protected void writeLeaf(Element e) throws IOException
+ {
+ // NOTE: Haven't tested if this is correct.
+ if(e.getName().equals(StyleConstants.IconElementName))
+ writeImage(e);
+ else
+ writeComponent(e);
+ }
+
+ /**
+ * Write the HTML attributes which do not have tag equivalents,
+ * e.g. attributes other than bold/italic/underlined.
+ */
+ protected void writeNonHTMLAttributes(AttributeSet attr) throws IOException
+ {
+ String style = "";
+
+ // Alignment? Background?
+
+ if( StyleConstants.getForeground(attr) != null )
+ style = style + "color: " +
+ getColor(StyleConstants.getForeground(attr)) + "; ";
+
+ style = style + "font-size: "+StyleConstants.getFontSize(attr)+"pt; ";
+ style = style + "font-family: "+StyleConstants.getFontFamily(attr);
+
+ startFontTag(style);
+ }
+
+ /**
+ * Write the styles used.
+ */
+ protected void writeStyles() throws IOException
+ {
+ if(doc instanceof DefaultStyledDocument)
+ {
+ Enumeration styles = ((DefaultStyledDocument)doc).getStyleNames();
+ while(styles.hasMoreElements())
+ writeStyle(doc.getStyle((String)styles.nextElement()));
+ }
+ else
+ { // What else to do here?
+ Style s = (Style)doc.getStyle("default");
+ if(s != null)
+ writeStyle( s );
+ }
+ }
+
+ /**
+ * Write a set of attributes.
+ */
+ protected void writeAttributes(AttributeSet attr) throws IOException
+ {
+ Enumeration attribs = attr.getAttributeNames();
+ while(attribs.hasMoreElements())
+ {
+ Object attribName = attribs.nextElement();
+ String name = attribName.toString();
+ String output = getAttribute(name, attr.getAttribute(attribName));
+ if( output != null )
+ {
+ indent();
+ write( output + NEWLINE );
+ }
+ }
+ }
+
+ /**
+ * Deliberately unimplemented, handles component elements.
+ */
+ protected void writeComponent(Element elem) throws IOException
+ {
+ }
+
+ /**
+ * Deliberately unimplemented.
+ * Writes StyleConstants.IconElementName elements.
+ */
+ protected void writeImage(Element elem) throws IOException
+ {
+ }
+
+ // -------------------- Private methods. --------------------------------
+
+ /**
+ * Write a single style attribute
+ */
+ private String getAttribute(String name, Object a) throws IOException
+ {
+ if(name.equals("foreground"))
+ return "foreground:"+getColor((Color)a)+";";
+ if(name.equals("background"))
+ return "background:"+getColor((Color)a)+";";
+ if(name.equals("italic"))
+ return "italic:"+(((Boolean)a).booleanValue() ? "italic;" : ";");
+ if(name.equals("bold"))
+ return "bold:"+(((Boolean)a).booleanValue() ? "bold;" : "normal;");
+ if(name.equals("family"))
+ return "family:" + a + ";";
+ if(name.equals("size"))
+ {
+ int size = ((Integer)a).intValue();
+ int htmlSize;
+ if( size > 24 )
+ htmlSize = 7;
+ else if( size > 18 )
+ htmlSize = 6;
+ else if( size > 14 )
+ htmlSize = 5;
+ else if( size > 12 )
+ htmlSize = 4;
+ else if( size > 10 )
+ htmlSize = 3;
+ else if( size > 8 )
+ htmlSize = 2;
+ else
+ htmlSize = 1;
+
+ return "size:" + htmlSize + ";";
+ }
+
+ return null;
+ }
+
+ /**
+ * Stupid that Color doesn't have a method for this.
+ */
+ private String getColor(Color c)
+ {
+ String r = "00" + Integer.toHexString(c.getRed());
+ r = r.substring(r.length() - 2);
+ String g = "00" + Integer.toHexString(c.getGreen());
+ g = g.substring(g.length() - 2);
+ String b = "00" + Integer.toHexString(c.getBlue());
+ b = b.substring(b.length() - 2);
+ return "#" + r + g + b;
+ }
+
+ /**
+ * Empty the stack of open tags
+ */
+ private void endOpenTags() throws IOException
+ {
+ while(!tagStack.empty())
+ write((String)tagStack.pop());
+
+ if( inFontTag() )
+ {
+ write(""+NEWLINE);
+ endFontTag();
+ }
+ }
+
+ /**
+ * Output a single style
+ */
+ private void writeStyle(Style s) throws IOException
+ {
+ if( s == null )
+ return;
+
+ writeStartTag("p."+s.getName()+" {");
+ writeAttributes(s);
+ writeEndTag("}");
+ }
+
+ private boolean hasText(Element e) throws BadLocationException
+ {
+ return (getText(e).trim().length() > 0);
+ }
+}
diff --git a/javax/swing/tree/AbstractLayoutCache.java b/javax/swing/tree/AbstractLayoutCache.java
index 8dbdd2f5e..155343f5b 100644
--- a/javax/swing/tree/AbstractLayoutCache.java
+++ b/javax/swing/tree/AbstractLayoutCache.java
@@ -1,5 +1,5 @@
/* AbstractLayoutCache.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,13 +38,10 @@ exception statement from your version. */
package javax.swing.tree;
-import gnu.classpath.NotImplementedException;
-
import java.awt.Rectangle;
import java.util.Enumeration;
import javax.swing.event.TreeModelEvent;
-import javax.swing.tree.VariableHeightLayoutCache.NodeRecord;
/**
* class AbstractLayoutCache
@@ -275,7 +272,7 @@ public abstract class AbstractLayoutCache
for (int i = 0; i < n; i++)
{
TreePath path = getPathForRow(i);
- r.setBounds(0,0,0,0);
+ r.setBounds(0, 0, 0, 0);
r = getBounds(path, r);
if (r.x + r.width > maximalWidth)
maximalWidth = r.x + r.width;
diff --git a/javax/swing/tree/DefaultMutableTreeNode.java b/javax/swing/tree/DefaultMutableTreeNode.java
index be8317f97..6951b9600 100644
--- a/javax/swing/tree/DefaultMutableTreeNode.java
+++ b/javax/swing/tree/DefaultMutableTreeNode.java
@@ -887,8 +887,7 @@ public class DefaultMutableTreeNode
return false;
if (node == this)
return true;
- return (node.getParent() == getParent()
- && getParent() != null);
+ return node.getParent() == getParent() && getParent() != null;
}
/**
@@ -1070,7 +1069,7 @@ public class DefaultMutableTreeNode
public Object nextElement()
{
- if(queue.isEmpty())
+ if (queue.isEmpty())
throw new NoSuchElementException("No more elements left.");
TreeNode node = (TreeNode) queue.removeFirst();
@@ -1105,7 +1104,7 @@ public class DefaultMutableTreeNode
public Object nextElement()
{
- if( next == null )
+ if (next == null)
throw new NoSuchElementException("No more elements left.");
Object current = next;
@@ -1121,7 +1120,7 @@ public class DefaultMutableTreeNode
private TreeNode traverse(Enumeration children)
{
// If more children are available step down.
- if( children.hasMoreElements() )
+ if (children.hasMoreElements())
{
TreeNode child = (TreeNode) children.nextElement();
childrenEnums.push(child.children());
@@ -1134,7 +1133,7 @@ public class DefaultMutableTreeNode
// If there are no more levels left, there is no next
// element to return.
- if ( childrenEnums.isEmpty() )
+ if (childrenEnums.isEmpty())
return null;
else
{
@@ -1165,7 +1164,7 @@ public class DefaultMutableTreeNode
public Object nextElement()
{
- if( nodes.isEmpty() )
+ if (nodes.isEmpty())
throw new NoSuchElementException("No more elements left!");
Enumeration children = (Enumeration) childrenEnums.peek();
@@ -1175,7 +1174,7 @@ public class DefaultMutableTreeNode
private Object traverse(Enumeration children)
{
- if ( children.hasMoreElements() )
+ if (children.hasMoreElements())
{
TreeNode node = (TreeNode) children.nextElement();
nodes.push(node);
diff --git a/javax/swing/tree/DefaultTreeCellRenderer.java b/javax/swing/tree/DefaultTreeCellRenderer.java
index 5e93145ae..e120b71c1 100644
--- a/javax/swing/tree/DefaultTreeCellRenderer.java
+++ b/javax/swing/tree/DefaultTreeCellRenderer.java
@@ -1,5 +1,5 @@
/* DefaultTreeCellRenderer.java
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -47,16 +47,17 @@ import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;
-import javax.swing.border.Border;
import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.JTree;
-import javax.swing.UIManager;
+import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.border.Border;
import javax.swing.plaf.UIResource;
/**
- * DefaultTreeCellRenderer
+ * A default implementation of the {@link TreeCellRenderer} interface.
*
* @author Andrew Selkirk
*/
@@ -64,71 +65,81 @@ public class DefaultTreeCellRenderer
extends JLabel
implements TreeCellRenderer
{
- // -------------------------------------------------------------
- // Variables --------------------------------------------------
- // -------------------------------------------------------------
/**
- * selected
+ * A flag indicating the current selection status.
*/
protected boolean selected;
/**
- * hasFocus
+ * A flag indicating the current focus status.
*/
protected boolean hasFocus;
/**
- * drawsFocusBorderAroundIcon
+ * drawsFocusBorderAroundIcon // FIXME: is this used?
*/
private boolean drawsFocusBorderAroundIcon;
/**
- * closedIcon
+ * The icon used to represent non-leaf nodes that are closed.
+ *
+ * @see #setClosedIcon(Icon)
*/
protected transient Icon closedIcon;
/**
- * leafIcon
+ * The icon used to represent leaf nodes.
+ *
+ * @see #setLeafIcon(Icon)
*/
protected transient Icon leafIcon;
/**
- * openIcon
+ * The icon used to represent non-leaf nodes that are open.
+ *
+ * @see #setOpenIcon(Icon)
*/
protected transient Icon openIcon;
/**
- * textSelectionColor
+ * The color used for text in selected cells.
+ *
+ * @see #setTextSelectionColor(Color)
*/
protected Color textSelectionColor;
/**
- * textNonSelectionColor
+ * The color used for text in non-selected cells.
+ *
+ * @see #setTextNonSelectionColor(Color)
*/
protected Color textNonSelectionColor;
/**
- * backgroundSelectionColor
+ * The background color for selected cells.
+ *
+ * @see #setBackgroundSelectionColor(Color)
*/
protected Color backgroundSelectionColor;
/**
- * backgroundNonSelectionColor
+ * The background color for non-selected cells.
+ *
+ * @see #setBackgroundNonSelectionColor(Color)
*/
protected Color backgroundNonSelectionColor;
/**
- * borderSelectionColor
+ * The border color for selected tree cells.
+ *
+ * @see #setBorderSelectionColor(Color)
*/
protected Color borderSelectionColor;
- // -------------------------------------------------------------
- // Initialization ---------------------------------------------
- // -------------------------------------------------------------
-
/**
- * Constructor DefaultTreeCellRenderer
+ * Creates a new tree cell renderer with defaults appropriate for the
+ * current {@link LookAndFeel}.
*/
public DefaultTreeCellRenderer()
{
@@ -138,19 +149,17 @@ public class DefaultTreeCellRenderer
setTextNonSelectionColor(UIManager.getColor("Tree.textForeground"));
setTextSelectionColor(UIManager.getColor("Tree.selectionForeground"));
- setBackgroundNonSelectionColor(UIManager.getColor("Tree.nonSelectionBackground"));
+ setBackgroundNonSelectionColor(UIManager.getColor("Tree.textBackground"));
setBackgroundSelectionColor(UIManager.getColor("Tree.selectionBackground"));
setBorderSelectionColor(UIManager.getColor("Tree.selectionBorderColor"));
}
- // -------------------------------------------------------------
- // Methods ----------------------------------------------------
- // -------------------------------------------------------------
-
/**
- * getDefaultOpenIcon
+ * Returns the default icon for non-leaf tree cells that are open (expanded).
+ * The icon is fetched from the defaults table for the current
+ * {@link LookAndFeel} using the key <code>Tree.openIcon</code>.
*
- * @returns Icon
+ * @return The default icon.
*/
public Icon getDefaultOpenIcon()
{
@@ -158,9 +167,11 @@ public class DefaultTreeCellRenderer
}
/**
- * getDefaultClosedIcon
+ * Returns the default icon for non-leaf tree cells that are closed (not
+ * expanded). The icon is fetched from the defaults table for the current
+ * {@link LookAndFeel} using the key <code>Tree.closedIcon</code>.
*
- * @returns Icon
+ * @return The default icon.
*/
public Icon getDefaultClosedIcon()
{
@@ -168,9 +179,11 @@ public class DefaultTreeCellRenderer
}
/**
- * getDefaultLeafIcon
+ * Returns the default icon for leaf tree cells. The icon is fetched from
+ * the defaults table for the current {@link LookAndFeel} using the key
+ * <code>Tree.leafIcon</code>.
*
- * @returns Icon
+ * @return The default icon.
*/
public Icon getDefaultLeafIcon()
{
@@ -178,20 +191,25 @@ public class DefaultTreeCellRenderer
}
/**
- * setOpenIcon
+ * Sets the icon to be displayed for non-leaf nodes that are open (expanded).
+ * Set this to <code>null</code> if no icon is required.
+ *
+ * @param icon the icon (<code>null</code> permitted).
*
- * @param i
- * the icon.
+ * @see #getOpenIcon()
*/
- public void setOpenIcon(Icon i)
+ public void setOpenIcon(Icon icon)
{
- openIcon = i;
+ openIcon = icon;
}
/**
- * getOpenIcon
+ * Returns the icon displayed for non-leaf nodes that are open (expanded).
+ * The default value is initialised from the {@link LookAndFeel}.
*
- * @returns Icon
+ * @return The open icon (possibly <code>null</code>).
+ *
+ * @see #setOpenIcon(Icon)
*/
public Icon getOpenIcon()
{
@@ -199,20 +217,25 @@ public class DefaultTreeCellRenderer
}
/**
- * setClosedIcon
+ * Sets the icon to be displayed for non-leaf nodes that are closed. Set
+ * this to <code>null</code> if no icon is required.
+ *
+ * @param icon the icon (<code>null</code> permitted).
*
- * @param i
- * the icon.
+ * @see #getClosedIcon()
*/
- public void setClosedIcon(Icon i)
+ public void setClosedIcon(Icon icon)
{
- closedIcon = i;
+ closedIcon = icon;
}
/**
- * getClosedIcon
+ * Returns the icon displayed for non-leaf nodes that are closed. The
+ * default value is initialised from the {@link LookAndFeel}.
+ *
+ * @return The closed icon (possibly <code>null</code>).
*
- * @returns Icon
+ * @see #setClosedIcon(Icon)
*/
public Icon getClosedIcon()
{
@@ -220,20 +243,25 @@ public class DefaultTreeCellRenderer
}
/**
- * setLeafIcon
+ * Sets the icon to be displayed for leaf nodes. Set this to
+ * <code>null</code> if no icon is required.
*
- * @param i
- * the icon.
+ * @param icon the icon (<code>null</code> permitted).
+ *
+ * @see #getLeafIcon()
*/
- public void setLeafIcon(Icon i)
+ public void setLeafIcon(Icon icon)
{
- leafIcon = i;
+ leafIcon = icon;
}
/**
- * getLeafIcon
+ * Returns the icon displayed for leaf nodes. The default value is
+ * initialised from the {@link LookAndFeel}.
+ *
+ * @return The leaf icon (possibly <code>null</code>).
*
- * @returns Icon
+ * @see #setLeafIcon(Icon)
*/
public Icon getLeafIcon()
{
@@ -241,10 +269,11 @@ public class DefaultTreeCellRenderer
}
/**
- * setTextSelectionColor
+ * Sets the text color for tree cells that are selected.
*
- * @param c
- * the color.
+ * @param c the color (<code>null</code> permitted).
+ *
+ * @see #getTextSelectionColor()
*/
public void setTextSelectionColor(Color c)
{
@@ -252,9 +281,13 @@ public class DefaultTreeCellRenderer
}
/**
- * getTextSelectionColor
+ * Returns the text color for tree cells that are selected.
+ * The default value is obtained from the {@link LookAndFeel} defaults
+ * table using the key <code>Tree.selectionForeground</code>.
+ *
+ * @return The text color for tree cells that are selected.
*
- * @returns Color
+ * @see #setTextSelectionColor(Color)
*/
public Color getTextSelectionColor()
{
@@ -262,10 +295,11 @@ public class DefaultTreeCellRenderer
}
/**
- * setTextNonSelectionColor
+ * Sets the text color for tree cells that are not selected.
+ *
+ * @param c the color (<code>null</code> permitted).
*
- * @param c
- * the color.
+ * @see #getTextNonSelectionColor()
*/
public void setTextNonSelectionColor(Color c)
{
@@ -273,9 +307,13 @@ public class DefaultTreeCellRenderer
}
/**
- * getTextNonSelectionColor
+ * Returns the text color for tree cells that are not selected.
+ * The default value is obtained from the {@link LookAndFeel} defaults
+ * table using the key <code>Tree.selectionForeground</code>.
*
- * @returns Color
+ * @return The background color for tree cells that are not selected.
+ *
+ * @see #setTextgroundNonSelectionColor(Color)
*/
public Color getTextNonSelectionColor()
{
@@ -283,10 +321,11 @@ public class DefaultTreeCellRenderer
}
/**
- * setBackgroundSelectionColor
+ * Sets the background color for tree cells that are selected.
+ *
+ * @param c the color (<code>null</code> permitted).
*
- * @param c
- * the color.
+ * @see #getBackgroundSelectionColor()
*/
public void setBackgroundSelectionColor(Color c)
{
@@ -294,9 +333,13 @@ public class DefaultTreeCellRenderer
}
/**
- * getBackgroundSelectionColor
+ * Returns the background color for tree cells that are selected.
+ * The default value is obtained from the {@link LookAndFeel} defaults
+ * table using the key <code>Tree.selectionBackground</code>.
*
- * @returns Color
+ * @return The background color for tree cells that are selected.
+ *
+ * @see #setBackgroundSelectionColor(Color)
*/
public Color getBackgroundSelectionColor()
{
@@ -304,10 +347,11 @@ public class DefaultTreeCellRenderer
}
/**
- * setBackgroundNonSelectionColor
+ * Sets the background color for tree cells that are not selected.
+ *
+ * @param c the color (<code>null</code> permitted).
*
- * @param c
- * the color.
+ * @see #getBackgroundNonSelectionColor()
*/
public void setBackgroundNonSelectionColor(Color c)
{
@@ -315,9 +359,13 @@ public class DefaultTreeCellRenderer
}
/**
- * getBackgroundNonSelectionColor
+ * Returns the background color for tree cells that are not selected.
+ * The default value is obtained from the {@link LookAndFeel} defaults
+ * table using the key <code>Tree.textBackground</code>.
+ *
+ * @return The background color for tree cells that are not selected.
*
- * @returns Color
+ * @see #setBackgroundNonSelectionColor(Color)
*/
public Color getBackgroundNonSelectionColor()
{
@@ -325,10 +373,11 @@ public class DefaultTreeCellRenderer
}
/**
- * setBorderSelectionColor
+ * Sets the border color for tree cells that are selected.
*
- * @param c
- * the color.
+ * @param c the color (<code>null</code> permitted).
+ *
+ * @see #getBorderSelectionColor()
*/
public void setBorderSelectionColor(Color c)
{
@@ -336,9 +385,13 @@ public class DefaultTreeCellRenderer
}
/**
- * getBorderSelectionColor
+ * Returns the border color for tree cells that are selected.
+ * The default value is obtained from the {@link LookAndFeel} defaults
+ * table using the key <code>Tree.selectionBorderColor</code>.
+ *
+ * @return The border color for tree cells that are selected.
*
- * @returns Color
+ * @see #setBorderSelectionColor(Color)
*/
public Color getBorderSelectionColor()
{
@@ -346,10 +399,11 @@ public class DefaultTreeCellRenderer
}
/**
- * setFont
+ * Sets the font.
*
- * @param f
- * the font.
+ * @param f the font.
+ *
+ * @see #getFont()
*/
public void setFont(Font f)
{
@@ -359,10 +413,9 @@ public class DefaultTreeCellRenderer
}
/**
- * setBackground
+ * Sets the background color.
*
- * @param c
- * the color.
+ * @param c the color.
*/
public void setBackground(Color c)
{
@@ -372,23 +425,18 @@ public class DefaultTreeCellRenderer
}
/**
- * getTreeCellRendererComponent
+ * Returns a component (in fact <code>this</code>) that can be used to
+ * render a tree cell with the specified state.
+ *
+ * @param tree the tree that the cell belongs to.
+ * @param val the cell value.
+ * @param selected indicates whether or not the cell is selected.
+ * @param expanded indicates whether or not the cell is expanded.
+ * @param leaf indicates whether or not the cell is a leaf in the tree.
+ * @param row the row index.
+ * @param hasFocus indicates whether or not the cell has the focus.
*
- * @param tree
- * TODO
- * @param val
- * TODO
- * @param selected
- * TODO
- * @param expanded
- * TODO
- * @param leaf
- * TODO
- * @param row
- * TODO
- * @param hasFocus
- * TODO
- * @returns Component
+ * @return <code>this</code>.
*/
public Component getTreeCellRendererComponent(JTree tree, Object val,
boolean selected,
@@ -433,9 +481,11 @@ public class DefaultTreeCellRenderer
}
/**
- * getFont
+ * Returns the current font.
+ *
+ * @return The current font.
*
- * @return the current Font
+ * @see #setFont(Font)
*/
public Font getFont()
{
@@ -460,7 +510,7 @@ public class DefaultTreeCellRenderer
insets = border.getBorderInsets(this);
FontMetrics fm = getToolkit().getFontMetrics(getFont());
- SwingUtilities.layoutCompoundLabel(((JLabel) this), fm, getText(),
+ SwingUtilities.layoutCompoundLabel((JLabel) this, fm, getText(),
getIcon(), getVerticalAlignment(),
getHorizontalAlignment(),
getVerticalTextPosition(),
@@ -471,7 +521,7 @@ public class DefaultTreeCellRenderer
Rectangle bounds = getBounds(ir);
bounds.x = tr.x - insets.left;
- bounds.width = tr.width + insets.left+insets.right;
+ bounds.width = tr.width + insets.left + insets.right;
g.setColor(super.getBackground());
g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
@@ -491,9 +541,9 @@ public class DefaultTreeCellRenderer
}
/**
- * returns the preferred size of the cell.
+ * Returns the preferred size of the cell.
*
- * @returns Dimension
+ * @return The preferred size of the cell.
*/
public Dimension getPreferredSize()
{
@@ -502,7 +552,7 @@ public class DefaultTreeCellRenderer
Rectangle tr = new Rectangle();
FontMetrics fm = getToolkit().getFontMetrics(getFont());
- SwingUtilities.layoutCompoundLabel(((JLabel) this), fm, getText(),
+ SwingUtilities.layoutCompoundLabel((JLabel) this, fm, getText(),
getIcon(), getVerticalAlignment(),
getHorizontalAlignment(),
getVerticalTextPosition(),
@@ -510,182 +560,156 @@ public class DefaultTreeCellRenderer
getIconTextGap());
Rectangle cr = ir.union(tr);
return new Dimension(cr.width, cr.height);
- } // getPreferredSize()
+ }
/**
- * validate
+ * For performance reasons, this method is overridden to do nothing.
*/
public void validate()
{
// Overridden for performance reasons.
- } // validate()
+ }
/**
- * revalidate
+ * For performance reasons, this method is overridden to do nothing.
*/
public void revalidate()
{
// Overridden for performance reasons.
- } // revalidate()
+ }
/**
- * repaint
+ * For performance reasons, this method is overridden to do nothing.
*
- * @param value0
- * TODO
- * @param value1
- * TODO
- * @param value2
- * TODO
- * @param value3
- * TODO
- * @param value4
- * TODO
+ * @param tm ignored
+ * @param x coordinate of the region to mark as dirty
+ * @param y coordinate of the region to mark as dirty
+ * @param width dimension of the region to mark as dirty
+ * @param height dimension of the region to mark as dirty
*/
- public void repaint(long value0, int value1, int value2, int value3,
- int value4)
+ public void repaint(long tm, int x, int y, int width, int height)
{
// Overridden for performance reasons.
- } // repaint()
+ }
/**
- * repaint
+ * For performance reasons, this method is overridden to do nothing.
*
- * @param value0
- * TODO
+ * @param area the area to repaint.
*/
- public void repaint(Rectangle value0)
+ public void repaint(Rectangle area)
{
// Overridden for performance reasons.
- } // repaint()
+ }
/**
- * firePropertyChange
+ * For performance reasons, this method is overridden to do nothing.
*
- * @param value0
- * TODO
- * @param value1
- * TODO
- * @param value2
- * TODO
+ * @param name the property name.
+ * @param oldValue the old value.
+ * @param newValue the new value.
*/
- protected void firePropertyChange(String value0, Object value1, Object value2)
+ protected void firePropertyChange(String name, Object oldValue,
+ Object newValue)
{
// Overridden for performance reasons.
- } // firePropertyChange()
+ }
/**
- * firePropertyChange
+ * For performance reasons, this method is overridden to do nothing.
*
- * @param value0
- * TODO
- * @param value1
- * TODO
- * @param value2
- * TODO
+ * @param name the property name.
+ * @param oldValue the old value.
+ * @param newValue the new value.
*/
- public void firePropertyChange(String value0, byte value1, byte value2)
+ public void firePropertyChange(String name, byte oldValue, byte newValue)
{
// Overridden for performance reasons.
- } // firePropertyChange()
+ }
/**
- * firePropertyChange
+ * For performance reasons, this method is overridden to do nothing.
*
- * @param value0
- * TODO
- * @param value1
- * TODO
- * @param value2
- * TODO
+ * @param name the property name.
+ * @param oldValue the old value.
+ * @param newValue the new value.
*/
- public void firePropertyChange(String value0, char value1, char value2)
+ public void firePropertyChange(String name, char oldValue, char newValue)
{
// Overridden for performance reasons.
- } // firePropertyChange()
+ }
/**
- * firePropertyChange
+ * For performance reasons, this method is overridden to do nothing.
*
- * @param value0
- * TODO
- * @param value1
- * TODO
- * @param value2
- * TODO
+ * @param name the property name.
+ * @param oldValue the old value.
+ * @param newValue the new value.
*/
- public void firePropertyChange(String value0, short value1, short value2)
+ public void firePropertyChange(String name, short oldValue, short newValue)
{
// Overridden for performance reasons.
- } // firePropertyChange()
+ }
/**
- * firePropertyChange
+ * For performance reasons, this method is overridden to do nothing.
*
- * @param value0
- * TODO
- * @param value1
- * TODO
- * @param value2
- * TODO
+ * @param name the property name.
+ * @param oldValue the old value.
+ * @param newValue the new value.
*/
- public void firePropertyChange(String value0, int value1, int value2)
+ public void firePropertyChange(String name, int oldValue, int newValue)
{
// Overridden for performance reasons.
- } // firePropertyChange()
+ }
/**
- * firePropertyChange
+ * For performance reasons, this method is overridden to do nothing.
*
- * @param value0
- * TODO
- * @param value1
- * TODO
- * @param value2
- * TODO
+ * @param name the property name.
+ * @param oldValue the old value.
+ * @param newValue the new value.
*/
- public void firePropertyChange(String value0, long value1, long value2)
+ public void firePropertyChange(String name, long oldValue, long newValue)
{
// Overridden for performance reasons.
- } // firePropertyChange()
+ }
/**
- * firePropertyChange
+ * For performance reasons, this method is overridden to do nothing.
*
- * @param value0
- * TODO
- * @param value1
- * TODO
- * @param value2
- * TODO
+ * @param name the property name.
+ * @param oldValue the old value.
+ * @param newValue the new value.
*/
- public void firePropertyChange(String value0, float value1, float value2)
+ public void firePropertyChange(String name, float oldValue, float newValue)
{
// Overridden for performance reasons.
- } // firePropertyChange()
+ }
/**
- * firePropertyChange
+ * For performance reasons, this method is overridden to do nothing.
*
- * @param value0 TODO
- * @param value1 TODO
- * @param value2 TODO
+ * @param name the property name.
+ * @param oldValue the old value.
+ * @param newValue the new value.
*/
- public void firePropertyChange(String value0, double value1, double value2)
+ public void firePropertyChange(String name, double oldValue, double newValue)
{
// Overridden for performance reasons.
- } // firePropertyChange()
+ }
/**
- * firePropertyChange
+ * For performance reasons, this method is overridden to do nothing.
*
- * @param name the property name.
- * @param v1 the old value.
- * @param v2 the new value.
+ * @param name the property name.
+ * @param oldValue the old value.
+ * @param newValue the new value.
*/
- public void firePropertyChange(String name, boolean v1, boolean v2)
+ public void firePropertyChange(String name, boolean oldValue,
+ boolean newValue)
{
// Overridden for performance reasons.
- } // firePropertyChange()
+ }
-} // DefaultTreeCellRenderer
+}
diff --git a/javax/swing/tree/DefaultTreeModel.java b/javax/swing/tree/DefaultTreeModel.java
index c1ca679d0..5819d15b6 100644
--- a/javax/swing/tree/DefaultTreeModel.java
+++ b/javax/swing/tree/DefaultTreeModel.java
@@ -1,5 +1,5 @@
/* DefaultTreeModel.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,8 +37,6 @@ exception statement from your version. */
package javax.swing.tree;
-import gnu.classpath.NotImplementedException;
-
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
@@ -62,7 +60,7 @@ public class DefaultTreeModel
/**
* root
*/
- protected TreeNode root = null;
+ protected TreeNode root;
/**
* listenerList
diff --git a/javax/swing/tree/DefaultTreeSelectionModel.java b/javax/swing/tree/DefaultTreeSelectionModel.java
index e47f42cab..0684ef766 100644
--- a/javax/swing/tree/DefaultTreeSelectionModel.java
+++ b/javax/swing/tree/DefaultTreeSelectionModel.java
@@ -121,7 +121,7 @@ public class DefaultTreeSelectionModel
/**
* The row of the last added path according to the RowMapper.
*/
- protected int leadRow;
+ protected int leadRow = -1;
/**
* Constructs a new DefaultTreeSelectionModel.
@@ -147,9 +147,9 @@ public class DefaultTreeSelectionModel
// Clone the selection and the list selection model.
cloned.selection = (TreePath[]) selection.clone();
- if (listSelectionModel!=null)
- cloned.listSelectionModel =
- (DefaultListSelectionModel) listSelectionModel.clone();
+ if (listSelectionModel != null)
+ cloned.listSelectionModel
+ = (DefaultListSelectionModel) listSelectionModel.clone();
return cloned;
}
@@ -171,7 +171,7 @@ public class DefaultTreeSelectionModel
b.append(getRow(selection[i]));
b.append(' ');
}
- b.append(", lead "+getLeadSelectionRow());
+ b.append(", lead " + getLeadSelectionRow());
return b.toString();
}
}
@@ -360,7 +360,7 @@ public class DefaultTreeSelectionModel
}
}
- if (path!=leadPath)
+ if (path != leadPath)
{
TreePath oldLead = leadPath;
leadPath = path;
@@ -445,7 +445,7 @@ public class DefaultTreeSelectionModel
// If the removed path was the lead path, set the lead path to null.
TreePath oldLead = leadPath;
- if (path!=null && leadPath!=null && path.equals(leadPath))
+ if (path != null && leadPath != null && path.equals(leadPath))
leadPath = null;
fireValueChanged(new TreeSelectionEvent(this, path, false, oldLead,
@@ -564,7 +564,7 @@ public class DefaultTreeSelectionModel
*/
public boolean isSelectionEmpty()
{
- return ((selection == null) || (selection.length == 0));
+ return (selection == null) || (selection.length == 0);
}
/**
@@ -841,7 +841,7 @@ public class DefaultTreeSelectionModel
if (leadIndex > 0 && leadIndex < selection.length)
setSelectionPath(selection[leadIndex]);
else
- setSelectionPath(selection[selection.length -1]);
+ setSelectionPath(selection[selection.length - 1]);
}
/**
@@ -882,7 +882,7 @@ public class DefaultTreeSelectionModel
for (int i = 1; i < rows.length; i++)
{
- if (rows[i-1] != rows[i] - 1)
+ if (rows[i - 1] != rows[i] - 1)
return false;
}
return true;
diff --git a/javax/swing/tree/ExpandVetoException.java b/javax/swing/tree/ExpandVetoException.java
index 1c8827c8a..57531d542 100644
--- a/javax/swing/tree/ExpandVetoException.java
+++ b/javax/swing/tree/ExpandVetoException.java
@@ -1,5 +1,5 @@
/* ExpandVetoException.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,47 +37,40 @@ exception statement from your version. */
package javax.swing.tree;
-// Imports
import javax.swing.event.TreeExpansionEvent;
/**
* ExpandVetoException
* @author Andrew Selkirk
*/
-public class ExpandVetoException extends Exception {
-
- //-------------------------------------------------------------
- // Variables --------------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * event
- */
- protected TreeExpansionEvent event = null;
-
-
- //-------------------------------------------------------------
- // Initialization ---------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * Constructor ExpandVetoException
- * @param event Tree Expansion Event
- */
- public ExpandVetoException(TreeExpansionEvent event) {
- super();
- this.event = event;
- } // ExpandVetoException()
-
- /**
- * Constructor ExpandVetoException
- * @param event Tree Expansion Event
- * @param message Message
- */
- public ExpandVetoException(TreeExpansionEvent event, String message) {
- super(message);
- this.event = event;
- } // ExpandVetoException()
-
-
-} // ExpandVetoException
+public class ExpandVetoException extends Exception
+{
+
+ /**
+ * event
+ */
+ protected TreeExpansionEvent event;
+
+
+ /**
+ * Constructor ExpandVetoException
+ * @param event Tree Expansion Event
+ */
+ public ExpandVetoException(TreeExpansionEvent event)
+ {
+ super();
+ this.event = event;
+ }
+
+ /**
+ * Constructor ExpandVetoException
+ * @param event Tree Expansion Event
+ * @param message Message
+ */
+ public ExpandVetoException(TreeExpansionEvent event, String message)
+ {
+ super(message);
+ this.event = event;
+ }
+
+}
diff --git a/javax/swing/tree/FixedHeightLayoutCache.java b/javax/swing/tree/FixedHeightLayoutCache.java
index 96655ce75..a699a6c9f 100644
--- a/javax/swing/tree/FixedHeightLayoutCache.java
+++ b/javax/swing/tree/FixedHeightLayoutCache.java
@@ -163,7 +163,7 @@ public class FixedHeightLayoutCache
{
// This method may be called in the context when the tree rectangle is
// not known. To work around this, it is assumed near infinitely large.
- if (bounds==null)
+ if (bounds == null)
bounds = getNodeDimensions(node, row, depth, isExpanded,
new Rectangle());
return bounds;
@@ -266,7 +266,7 @@ public class FixedHeightLayoutCache
if (expanded.contains(node))
{
int sc = treeModel.getChildCount(node);
- int deeper = depth+1;
+ int deeper = depth + 1;
for (int i = 0; i < sc; i++)
{
Object child = treeModel.getChild(node, i);
@@ -283,7 +283,7 @@ public class FixedHeightLayoutCache
public void invalidatePathBounds(TreePath path)
{
NodeRecord r = (NodeRecord) nodes.get(path.getLastPathComponent());
- if (r!=null)
+ if (r != null)
r.bounds = null;
}
diff --git a/javax/swing/tree/RowMapper.java b/javax/swing/tree/RowMapper.java
index 690efb77e..59eb1e3a9 100644
--- a/javax/swing/tree/RowMapper.java
+++ b/javax/swing/tree/RowMapper.java
@@ -1,5 +1,5 @@
/* RowMapper.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -41,14 +41,14 @@ package javax.swing.tree;
* RowMapper public interface
* @author Andrew Selkirk
*/
-public interface RowMapper {
+public interface RowMapper
+{
- /**
- * getRowsForPaths
- * @param path TreePath
- * @return TODO
- */
- int[] getRowsForPaths(TreePath[] path);
+ /**
+ * getRowsForPaths
+ * @param path TreePath
+ * @return TODO
+ */
+ int[] getRowsForPaths(TreePath[] path);
-
-} // RowMapper
+} \ No newline at end of file
diff --git a/javax/swing/tree/TreeNode.java b/javax/swing/tree/TreeNode.java
index 94f2c69f8..ae7380c70 100644
--- a/javax/swing/tree/TreeNode.java
+++ b/javax/swing/tree/TreeNode.java
@@ -45,7 +45,8 @@ import java.util.Enumeration;
*
* @author Andrew Selkirk
*/
-public interface TreeNode {
+public interface TreeNode
+{
/**
* Returns the parent node for this tree node, or <code>null</code> if this
diff --git a/javax/swing/tree/TreeSelectionModel.java b/javax/swing/tree/TreeSelectionModel.java
index 4072ccc64..9bdc99be3 100644
--- a/javax/swing/tree/TreeSelectionModel.java
+++ b/javax/swing/tree/TreeSelectionModel.java
@@ -1,5 +1,5 @@
/* TreeSelectionModel.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -46,39 +46,67 @@ import javax.swing.event.TreeSelectionListener;
* TreeSelectionModel public interface
* @author Andrew Selkirk
*/
-public interface TreeSelectionModel {
-
- int SINGLE_TREE_SELECTION = 1;
- int CONTIGUOUS_TREE_SELECTION = 2;
- int DISCONTIGUOUS_TREE_SELECTION = 4;
-
- void setSelectionMode(int mode);
- int getSelectionMode();
- void setSelectionPath(TreePath path);
- void setSelectionPaths(TreePath[] paths);
- void addSelectionPath(TreePath path);
- void addSelectionPaths(TreePath[] paths);
- void removeSelectionPath(TreePath path);
- void removeSelectionPaths(TreePath[] paths);
- TreePath getSelectionPath();
- TreePath[] getSelectionPaths();
- int getSelectionCount();
- boolean isPathSelected(TreePath path);
- boolean isSelectionEmpty();
- void clearSelection();
- void setRowMapper(RowMapper newMapper);
- RowMapper getRowMapper();
- int[] getSelectionRows();
- int getMinSelectionRow();
- int getMaxSelectionRow();
- boolean isRowSelected(int row);
- void resetRowSelection();
- int getLeadSelectionRow();
- TreePath getLeadSelectionPath();
- void addPropertyChangeListener(PropertyChangeListener listener);
- void removePropertyChangeListener(PropertyChangeListener listener);
- void addTreeSelectionListener(TreeSelectionListener x);
- void removeTreeSelectionListener(TreeSelectionListener x);
-
-
-} // TreeSelectionModel
+public interface TreeSelectionModel
+{
+
+ int SINGLE_TREE_SELECTION = 1;
+
+ int CONTIGUOUS_TREE_SELECTION = 2;
+
+ int DISCONTIGUOUS_TREE_SELECTION = 4;
+
+ void setSelectionMode(int mode);
+
+ int getSelectionMode();
+
+ void setSelectionPath(TreePath path);
+
+ void setSelectionPaths(TreePath[] paths);
+
+ void addSelectionPath(TreePath path);
+
+ void addSelectionPaths(TreePath[] paths);
+
+ void removeSelectionPath(TreePath path);
+
+ void removeSelectionPaths(TreePath[] paths);
+
+ TreePath getSelectionPath();
+
+ TreePath[] getSelectionPaths();
+
+ int getSelectionCount();
+
+ boolean isPathSelected(TreePath path);
+
+ boolean isSelectionEmpty();
+
+ void clearSelection();
+
+ void setRowMapper(RowMapper newMapper);
+
+ RowMapper getRowMapper();
+
+ int[] getSelectionRows();
+
+ int getMinSelectionRow();
+
+ int getMaxSelectionRow();
+
+ boolean isRowSelected(int row);
+
+ void resetRowSelection();
+
+ int getLeadSelectionRow();
+
+ TreePath getLeadSelectionPath();
+
+ void addPropertyChangeListener(PropertyChangeListener listener);
+
+ void removePropertyChangeListener(PropertyChangeListener listener);
+
+ void addTreeSelectionListener(TreeSelectionListener x);
+
+ void removeTreeSelectionListener(TreeSelectionListener x);
+
+}
diff --git a/javax/swing/tree/VariableHeightLayoutCache.java b/javax/swing/tree/VariableHeightLayoutCache.java
index a9ed552e6..3d5d3c508 100644
--- a/javax/swing/tree/VariableHeightLayoutCache.java
+++ b/javax/swing/tree/VariableHeightLayoutCache.java
@@ -162,7 +162,7 @@ public class VariableHeightLayoutCache
{
// This method may be called in the context when the tree rectangle is
// not known. To work around this, it is assumed near infinitely large.
- if (bounds==null)
+ if (bounds == null)
bounds = getNodeDimensions(node, row, depth, isExpanded,
new Rectangle());
return bounds;
@@ -265,7 +265,7 @@ public class VariableHeightLayoutCache
if (expanded.contains(node))
{
int sc = treeModel.getChildCount(node);
- int deeper = depth+1;
+ int deeper = depth + 1;
for (int i = 0; i < sc; i++)
{
Object child = treeModel.getChild(node, i);
@@ -282,7 +282,7 @@ public class VariableHeightLayoutCache
public void invalidatePathBounds(TreePath path)
{
NodeRecord r = (NodeRecord) nodes.get(path.getLastPathComponent());
- if (r!=null)
+ if (r != null)
r.bounds = null;
}
diff --git a/native/Makefile.am b/native/Makefile.am
index e2891cbb9..89b859eb7 100644
--- a/native/Makefile.am
+++ b/native/Makefile.am
@@ -8,6 +8,10 @@ if CREATE_GTK_PEER_LIBRARIES
JAWTDIR = jawt
endif
-SUBDIRS = fdlibm $(JNIDIR) $(JAWTDIR)
-DIST_SUBDIRS = fdlibm jni jawt
+if CREATE_PLUGIN
+ PLUGINDIR = plugin
+endif
+
+SUBDIRS = fdlibm $(JNIDIR) $(JAWTDIR) $(PLUGINDIR)
+DIST_SUBDIRS = fdlibm jni jawt plugin
diff --git a/native/jawt/Makefile.am b/native/jawt/Makefile.am
index b6e6f0af0..30e5a345b 100644
--- a/native/jawt/Makefile.am
+++ b/native/jawt/Makefile.am
@@ -1,16 +1,12 @@
-nativeexeclib_LTLIBRARIES = libjawtgnu.la
+nativeexeclib_LTLIBRARIES = libjawt.la
-libjawtgnu_la_SOURCES = jawt.c
-libjawtgnu_la_LIBADD = $(top_builddir)/native/jni/gtk-peer/libgtkpeer.la
-# FIXME: libtool doesn't allow overriding SONAME, but we need to set
-# it to libjawt.so for binary compatibility.
-#
-# libjawtgnu_la_LDFLAGS = -Wl,-soname -Wl,libjawt.so
+libjawt_la_SOURCES = jawt.c
+libjawt_la_LIBADD = $(top_builddir)/native/jni/gtk-peer/libgtkpeer.la
-AM_LDFLAGS = @CLASSPATH_MODULE@ @GTK_LIBS@ @CAIRO_LIBS@ @PANGOFT2_LIBS@ @X_LIBS@ -lXtst
+AM_LDFLAGS = @CLASSPATH_MODULE@ @GTK_LIBS@ @PANGOFT2_LIBS@ @X_LIBS@ -lXtst
AM_CPPFLAGS = @CLASSPATH_INCLUDES@
# Just the WARNING_CFLAGS. We cannot use the strict flags since the gtk
# headers contain broken prototypes (by design, see gtkitemfactory.h).
AM_CFLAGS = @WARNING_CFLAGS@ @ERROR_CFLAGS@ \
- @GTK_CFLAGS@ @CAIRO_CFLAGS@ @PANGOFT2_CFLAGS@
+ @GTK_CFLAGS@ @PANGOFT2_CFLAGS@
diff --git a/native/jni/classpath/jcl.h b/native/jni/classpath/jcl.h
index 514b78262..d358aeb9c 100644
--- a/native/jni/classpath/jcl.h
+++ b/native/jni/classpath/jcl.h
@@ -1,5 +1,5 @@
/* jcl.h
- Copyright (C) 1998 Free Software Foundation, Inc.
+ Copyright (C) 1998, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -50,6 +50,10 @@ typedef jlong jpointer;
#error "Unknown pointer size"
#endif
+/* Helper macros for going between pointers and jlongs. */
+#define JLONG_TO_PTR(T,P) ((T *)(long)P)
+#define PTR_TO_JLONG(P) ((jlong)(long)P)
+
JNIEXPORT jclass JNICALL JCL_FindClass (JNIEnv * env, const char *className);
JNIEXPORT void JNICALL JCL_ThrowException (JNIEnv * env,
const char *className,
diff --git a/native/jni/gtk-peer/Makefile.am b/native/jni/gtk-peer/Makefile.am
index 9c373cb4d..a4013cf37 100644
--- a/native/jni/gtk-peer/Makefile.am
+++ b/native/jni/gtk-peer/Makefile.am
@@ -1,17 +1,12 @@
nativeexeclib_LTLIBRARIES = libgtkpeer.la
-# Gtk/Cairo JNI sources.
-if GTK_CAIRO
- gtk_cairo_c_source_files = \
- gnu_java_awt_peer_gtk_GdkGraphics2D.c
-else
- gtk_cairo_c_source_files =
-endif
-
-libgtkpeer_la_SOURCES = $(gtk_cairo_c_source_files) \
+# GTK JNI sources.
+libgtkpeer_la_SOURCES = gnu_java_awt_peer_gtk_CairoSurface.c \
+ gnu_java_awt_peer_gtk_CairoGraphics2D.c \
+ gnu_java_awt_peer_gtk_ComponentGraphics.c \
+ gnu_java_awt_peer_gtk_ComponentGraphicsCopy.c \
gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.c \
gnu_java_awt_peer_gtk_GdkFontPeer.c \
- gnu_java_awt_peer_gtk_GdkGraphics.c \
gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.c \
gnu_java_awt_peer_gtk_GdkPixbufDecoder.c \
gnu_java_awt_peer_gtk_GdkRobotPeer.c \
@@ -44,22 +39,23 @@ libgtkpeer_la_SOURCES = $(gtk_cairo_c_source_files) \
gnu_java_awt_peer_gtk_GtkTextFieldPeer.c \
gnu_java_awt_peer_gtk_GtkToolkit.c \
gnu_java_awt_peer_gtk_GtkWindowPeer.c \
+ gnu_java_awt_peer_gtk_GtkVolatileImage.c \
+ cairographics2d.h \
gthread-jni.c \
gdkfont.h \
gthread-jni.h \
- gtkcairopeer.h \
gtk_jawt.c \
gtkpeer.h
libgtkpeer_la_LIBADD = $(top_builddir)/native/jni/classpath/native_state.lo \
$(top_builddir)/native/jni/classpath/jcl.lo
-AM_LDFLAGS = @CLASSPATH_MODULE@ @GTK_LIBS@ @CAIRO_LIBS@ @FREETYPE2_LIBS@ \
- @PANGOFT2_LIBS@ @X_PRE_LIBS@ @X_LIBS@ @X_EXTRA_LIBS@ -lX11 -lXtst
+AM_LDFLAGS = @CLASSPATH_MODULE@ @GTK_LIBS@ @FREETYPE2_LIBS@ \
+ @PANGOFT2_LIBS@ @X_PRE_LIBS@ @X_LIBS@ @X_EXTRA_LIBS@ @XTEST_LIBS@
AM_CPPFLAGS = @CLASSPATH_INCLUDES@
# Just the WARNING_CFLAGS. We cannot use the strict flags since the gtk
# headers contain broken prototypes (by design, see gtkitemfactory.h).
AM_CFLAGS = @WARNING_CFLAGS@ @ERROR_CFLAGS@ \
- @GTK_CFLAGS@ @CAIRO_CFLAGS@ @FREETYPE2_CFLAGS@ @PANGOFT2_CFLAGS@ \
+ @GTK_CFLAGS@ @FREETYPE2_CFLAGS@ @PANGOFT2_CFLAGS@ \
@X_CFLAGS@
diff --git a/native/jni/gtk-peer/cairographics2d.h b/native/jni/gtk-peer/cairographics2d.h
new file mode 100644
index 000000000..2c12384de
--- /dev/null
+++ b/native/jni/gtk-peer/cairographics2d.h
@@ -0,0 +1,119 @@
+/* cairographics2d.h --
+ 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. */
+
+#ifndef CAIROGRAPHICS2D_H
+#define CAIROGRAPHICS2D_H
+
+
+#include <cairo.h>
+#include <gtk/gtk.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <config.h>
+#include "native_state.h"
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#include <jni.h>
+
+/*
+ * These public final constants are part of the java2d public API, so we
+ * write them explicitly here to save fetching them from the constant pool
+ * all the time.
+ */
+enum java_awt_alpha_composite_rule
+ {
+ java_awt_alpha_composite_CLEAR = 1,
+ java_awt_alpha_composite_SRC = 2,
+ java_awt_alpha_composite_SRC_OVER = 3,
+ java_awt_alpha_composite_DST_OVER = 4,
+ java_awt_alpha_composite_SRC_IN = 5,
+ java_awt_alpha_composite_DST_IN = 6,
+ java_awt_alpha_composite_SRC_OUT = 7,
+ java_awt_alpha_composite_DST_OUT = 8,
+ java_awt_alpha_composite_DST = 9,
+ java_awt_alpha_composite_SRC_ATOP = 10,
+ java_awt_alpha_composite_DST_ATOP = 11,
+ java_awt_alpha_composite_XOR = 12
+ };
+
+enum java_awt_basic_stroke_join_rule
+ {
+ java_awt_basic_stroke_JOIN_MITER = 0,
+ java_awt_basic_stroke_JOIN_ROUND = 1,
+ java_awt_basic_stroke_JOIN_BEVEL = 2
+ };
+
+enum java_awt_basic_stroke_cap_rule
+ {
+ java_awt_basic_stroke_CAP_BUTT = 0,
+ java_awt_basic_stroke_CAP_ROUND = 1,
+ java_awt_basic_stroke_CAP_SQUARE = 2
+ };
+
+enum java_awt_geom_path_iterator_winding_rule
+ {
+ java_awt_geom_path_iterator_WIND_EVEN_ODD = 0,
+ java_awt_geom_path_iterator_WIND_NON_ZERO = 1
+ };
+
+enum java_awt_rendering_hints_filter
+ {
+ java_awt_rendering_hints_VALUE_INTERPOLATION_NEAREST_NEIGHBOR = 0,
+ java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR = 1,
+ java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED = 2,
+ java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY = 3,
+ java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT = 4
+
+ };
+
+/**
+ * A structure which basically contains the cairo_t pointer.
+ * The rest is for gradient and texture fills.
+ */
+struct cairographics2d
+{
+ cairo_t *cr;
+ cairo_surface_t *pattern_surface;
+ cairo_pattern_t *pattern;
+ char *pattern_pixels;
+};
+
+cairo_t *cp_gtk_get_cairo_t(JNIEnv *env,
+ jobject cairographics2dobj);
+
+#endif
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c
new file mode 100644
index 000000000..1cc8b8caa
--- /dev/null
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c
@@ -0,0 +1,699 @@
+/* gnu_java_awt_peer_gtk_CairoGraphics2d.c
+ 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. */
+
+#include "jcl.h"
+#include "gdkfont.h"
+#include "cairographics2d.h"
+#include "gnu_java_awt_peer_gtk_CairoGraphics2D.h"
+#include <gdk/gdktypes.h>
+#include <gdk/gdkprivate.h>
+#include <gdk/gdkx.h>
+
+#include <cairo-ft.h>
+#include <cairo-xlib.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static void install_font_peer(cairo_t *cr, struct peerfont *pfont);
+static void update_pattern_transform (struct cairographics2d *gr);
+static struct cairographics2d *getPointer(JNIEnv *env, jobject obj);
+
+static struct cairographics2d *
+getPointer(JNIEnv *env, jobject obj)
+{
+ jclass cls;
+ jlong value;
+ jfieldID nofid;
+ cls = (*env)->GetObjectClass( env, obj );
+ nofid = (*env)->GetFieldID( env, cls, "nativePointer", "J" );
+ value = (*env)->GetLongField( env, obj, nofid );
+ (*env)->DeleteLocalRef( env, cls );
+
+ return JLONG_TO_PTR(struct cairographics2d, value);
+}
+
+/**
+ * Returns the cairo_t * associated with a CairoGraphics2D object,
+ * This is used by GdkTextLayout.
+ */
+cairo_t *cp_gtk_get_cairo_t(JNIEnv *env,
+ jobject cairographics2dobj)
+{
+ struct cairographics2d *gr = getPointer(env, cairographics2dobj);
+ g_assert(gr != NULL);
+ return gr->cr;
+}
+
+/**
+ * Allocates the cairographics2d structure.
+ */
+JNIEXPORT jlong JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_init
+ (JNIEnv *env __attribute__ ((unused)),
+ jobject obj __attribute__ ((unused)),
+ jlong cairo_t_pointer)
+{
+ struct cairographics2d *g = NULL;
+ cairo_t *cr = JLONG_TO_PTR(cairo_t, cairo_t_pointer);
+ g_assert(cr != NULL);
+
+ g = (struct cairographics2d *) g_malloc (sizeof (struct cairographics2d));
+
+ g_assert (g != NULL);
+ memset (g, 0, sizeof(struct cairographics2d));
+ g->cr = cr;
+
+ return PTR_TO_JLONG(g);
+}
+
+/**
+ * Disposes of the cairographics2d structure.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_disposeNative
+ (JNIEnv *env, jobject obj)
+{
+ struct cairographics2d *gr = getPointer(env, obj);
+
+ if (gr == NULL)
+ return;
+
+ if (gr->cr)
+ cairo_destroy (gr->cr);
+
+ if (gr->pattern)
+ cairo_pattern_destroy (gr->pattern);
+ gr->pattern = NULL;
+
+ if (gr->pattern_surface)
+ cairo_surface_destroy (gr->pattern_surface);
+ gr->pattern_surface = NULL;
+
+ g_free( gr );
+}
+
+/**
+ * Set the gradient.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_setGradient
+ (JNIEnv *env, jobject obj,
+ jdouble x1, jdouble y1,
+ jdouble x2, jdouble y2,
+ jint r1, jint g1, jint b1, jint a1,
+ jint r2, jint g2, jint b2, jint a2,
+ jboolean cyclic)
+{
+ struct cairographics2d *gr = NULL;
+ cairo_pattern_t* pattern;
+ cairo_extend_t extend;
+
+ gr = getPointer (env, obj);
+ g_assert( gr != NULL );
+
+ pattern = cairo_pattern_create_linear(x1, y1, x2, y2);
+ g_assert( pattern != NULL );
+
+ cairo_pattern_add_color_stop_rgba(pattern, 0.0, r1 / 255.0, g1 / 255.0,
+ b1 / 255.0, a1 / 255.0);
+
+ cairo_pattern_add_color_stop_rgba(pattern, 1.0, r2 / 255.0, g2 / 255.0,
+ b2 / 255.0, a2 / 255.0);
+
+ extend = (cyclic == JNI_TRUE) ? CAIRO_EXTEND_REFLECT : CAIRO_EXTEND_NONE;
+
+ cairo_pattern_set_extend( pattern, extend );
+
+ gr->pattern = pattern;
+ cairo_set_source(gr->cr, gr->pattern);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_setTexturePixels
+ (JNIEnv *env, jobject obj, jintArray jarr, jint w, jint h, jint stride)
+{
+ struct cairographics2d *gr = NULL;
+ jint *jpixels = NULL;
+
+ gr = getPointer (env, obj);
+ g_assert (gr != NULL);
+
+ if (gr->pattern)
+ cairo_pattern_destroy (gr->pattern);
+
+ if (gr->pattern_surface)
+ cairo_surface_destroy (gr->pattern_surface);
+
+ if (gr->pattern_pixels)
+ g_free (gr->pattern_pixels);
+
+ gr->pattern = NULL;
+ gr->pattern_surface = NULL;
+ gr->pattern_pixels = NULL;
+
+ gr->pattern_pixels = (char *) g_malloc (h * stride * 4);
+ g_assert (gr->pattern_pixels != NULL);
+
+ jpixels = (*env)->GetIntArrayElements (env, jarr, NULL);
+ g_assert (jpixels != NULL);
+ memcpy (gr->pattern_pixels, jpixels, h * stride * 4);
+ (*env)->ReleaseIntArrayElements (env, jarr, jpixels, 0);
+
+ gr->pattern_surface = cairo_image_surface_create_for_data ((unsigned char *)gr->pattern_pixels,
+ CAIRO_FORMAT_ARGB32,
+ w, h, stride * 4);
+ g_assert (gr->pattern_surface != NULL);
+ gr->pattern = cairo_pattern_create_for_surface (gr->pattern_surface);
+ g_assert (gr->pattern != NULL);
+ cairo_pattern_set_extend (gr->pattern, CAIRO_EXTEND_REPEAT);
+ cairo_set_source (gr->cr, gr->pattern);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_drawPixels
+ (JNIEnv *env, jobject obj, jintArray java_pixels,
+ jint w, jint h, jint stride, jdoubleArray java_matrix)
+{
+ jint *native_pixels = NULL;
+ jdouble *native_matrix = NULL;
+ struct cairographics2d *gr = getPointer (env, obj);
+ g_assert (gr != NULL);
+
+ native_pixels = (*env)->GetIntArrayElements (env, java_pixels, NULL);
+ native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL);
+ g_assert (native_pixels != NULL);
+ g_assert (native_matrix != NULL);
+ g_assert ((*env)->GetArrayLength (env, java_matrix) == 6);
+
+ {
+ cairo_matrix_t mat;
+ cairo_pattern_t *p;
+ cairo_surface_t *surf = cairo_image_surface_create_for_data ((unsigned char *)native_pixels,
+ CAIRO_FORMAT_ARGB32,
+ w, h, stride * 4);
+ cairo_matrix_init_identity (&mat);
+ cairo_matrix_init (&mat,
+ native_matrix[0], native_matrix[1],
+ native_matrix[2], native_matrix[3],
+ native_matrix[4], native_matrix[5]);
+
+ p = cairo_pattern_create_for_surface (surf);
+ cairo_pattern_set_matrix (p, &mat);
+ if (gr->pattern)
+ cairo_pattern_set_filter (p, cairo_pattern_get_filter (gr->pattern));
+ cairo_set_source (gr->cr, p);
+ cairo_paint (gr->cr);
+ cairo_pattern_destroy (p);
+ cairo_surface_destroy (surf);
+ }
+
+ (*env)->ReleaseIntArrayElements (env, java_pixels, native_pixels, 0);
+ (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0);
+}
+
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSetMatrix
+ (JNIEnv *env, jobject obj, jdoubleArray java_matrix)
+{
+ jdouble *native_matrix = NULL;
+ struct cairographics2d *gr = getPointer (env, obj);
+
+ native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL);
+ g_assert (native_matrix != NULL);
+ g_assert ((*env)->GetArrayLength (env, java_matrix) == 6);
+
+ {
+ cairo_matrix_t mat;
+
+ cairo_matrix_init_identity (&mat);
+ cairo_matrix_init (&mat,
+ native_matrix[0], native_matrix[1],
+ native_matrix[2], native_matrix[3],
+ native_matrix[4], native_matrix[5]);
+ cairo_set_matrix (gr->cr, &mat);
+ }
+
+ (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0);
+ update_pattern_transform (gr);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoDrawGlyphVector
+ (JNIEnv *env, jobject obj,
+ jobject font,
+ jfloat x, jfloat y, jint n,
+ jintArray java_codes,
+ jfloatArray java_positions)
+{
+
+ struct cairographics2d *gr = NULL;
+ struct peerfont *pfont = NULL;
+ cairo_glyph_t *glyphs = NULL;
+ int *native_codes;
+ float *native_positions;
+ jint i = 0;
+
+ g_assert (obj != NULL);
+ g_assert (java_codes != NULL);
+ g_assert (java_positions != NULL);
+
+ gr = getPointer (env, obj);
+ g_assert (gr != NULL);
+
+ pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, font);
+ g_assert (pfont != NULL);
+
+ install_font_peer(gr->cr, pfont);
+
+ glyphs = g_malloc( sizeof(cairo_glyph_t) * n);
+ g_assert (glyphs != NULL);
+
+ native_codes = (*env)->GetIntArrayElements (env, java_codes, NULL);
+ native_positions = (*env)->GetFloatArrayElements (env, java_positions, NULL);
+
+ for (i = 0; i < n; ++i)
+ {
+ glyphs[i].index = native_codes[i];
+ glyphs[i].x = x + native_positions[ 2*i ];
+ glyphs[i].y = y + native_positions[ 2*i + 1];
+ }
+
+ (*env)->ReleaseFloatArrayElements (env, java_positions, native_positions, 0);
+ (*env)->ReleaseIntArrayElements (env, java_codes, native_codes, 0);
+
+ cairo_show_glyphs (gr->cr, glyphs, n);
+
+ g_free(glyphs);
+}
+
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSetOperator
+ (JNIEnv *env, jobject obj, jint op)
+{
+ struct cairographics2d *gr = getPointer (env, obj);
+ g_assert (gr != NULL);
+
+ switch ((enum java_awt_alpha_composite_rule) op)
+ {
+ case java_awt_alpha_composite_CLEAR:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_CLEAR);
+ break;
+
+ case java_awt_alpha_composite_SRC:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_SOURCE);
+ break;
+
+ case java_awt_alpha_composite_SRC_OVER:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_OVER);
+ break;
+
+ case java_awt_alpha_composite_DST_OVER:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_OVER);
+ break;
+
+ case java_awt_alpha_composite_SRC_IN:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_IN);
+ break;
+
+ case java_awt_alpha_composite_DST_IN:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_IN);
+ break;
+
+ case java_awt_alpha_composite_SRC_OUT:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_OUT);
+ break;
+
+ case java_awt_alpha_composite_DST_OUT:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_OUT);
+ break;
+
+ case java_awt_alpha_composite_DST:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST);
+ break;
+
+ case java_awt_alpha_composite_SRC_ATOP:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_ATOP);
+ break;
+
+ case java_awt_alpha_composite_DST_ATOP:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_ATOP);
+ break;
+
+ case java_awt_alpha_composite_XOR:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_XOR);
+ break;
+ }
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSetRGBAColor
+ (JNIEnv *env, jobject obj, jdouble r, jdouble g, jdouble b, jdouble a)
+{
+ struct cairographics2d *gr = getPointer (env, obj);
+ g_assert (gr != NULL);
+
+ cairo_set_source_rgba (gr->cr, r, g, b, a);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSetFillRule
+ (JNIEnv *env, jobject obj, jint rule)
+{
+ struct cairographics2d *gr = getPointer (env, obj);
+ g_assert (gr != NULL);
+
+ switch ((enum java_awt_geom_path_iterator_winding_rule) rule)
+ {
+ case java_awt_geom_path_iterator_WIND_NON_ZERO:
+ cairo_set_fill_rule (gr->cr, CAIRO_FILL_RULE_WINDING);
+ break;
+ case java_awt_geom_path_iterator_WIND_EVEN_ODD:
+ cairo_set_fill_rule (gr->cr, CAIRO_FILL_RULE_EVEN_ODD);
+ break;
+ }
+}
+
+/**
+ * Set the line style, except for dashes.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSetLine
+ (JNIEnv *env, jobject obj, jdouble width, int cap, int join, double miterLimit)
+{
+ struct cairographics2d *gr = getPointer (env, obj);
+ g_assert (gr != NULL);
+
+ /* set width */
+ cairo_set_line_width (gr->cr, width);
+
+ /* set cap */
+ switch ((enum java_awt_basic_stroke_cap_rule) cap)
+ {
+ case java_awt_basic_stroke_CAP_BUTT:
+ cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_BUTT);
+ break;
+
+ case java_awt_basic_stroke_CAP_ROUND:
+ cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_ROUND);
+ break;
+
+ case java_awt_basic_stroke_CAP_SQUARE:
+ cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_SQUARE);
+ break;
+ }
+
+ /* set join */
+ switch ((enum java_awt_basic_stroke_join_rule) join)
+ {
+ case java_awt_basic_stroke_JOIN_MITER:
+ cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_MITER);
+ break;
+
+ case java_awt_basic_stroke_JOIN_ROUND:
+ cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_ROUND);
+ break;
+
+ case java_awt_basic_stroke_JOIN_BEVEL:
+ cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_BEVEL);
+ break;
+ }
+
+ /* set miter */
+ cairo_set_miter_limit (gr->cr, miterLimit);
+}
+
+/**
+ * Set the line dashes
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSetDash
+ (JNIEnv *env, jobject obj, jdoubleArray dashes, jint ndash, jdouble offset)
+{
+ jdouble *dasharr = NULL;
+ struct cairographics2d *gr = getPointer (env, obj);
+ g_assert (gr != NULL);
+
+ dasharr = (*env)->GetDoubleArrayElements (env, dashes, NULL);
+ g_assert (dasharr != NULL);
+
+ cairo_set_dash (gr->cr, dasharr, ndash, offset);
+
+ (*env)->ReleaseDoubleArrayElements (env, dashes, dasharr, 0);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoNewPath
+ (JNIEnv *env, jobject obj)
+{
+ struct cairographics2d *gr = getPointer (env, obj);
+ g_assert (gr != NULL);
+
+ cairo_new_path (gr->cr);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoMoveTo
+ (JNIEnv *env, jobject obj, jdouble x, jdouble y)
+{
+ struct cairographics2d *gr = getPointer (env, obj);
+ g_assert (gr != NULL);
+
+ cairo_move_to (gr->cr, x, y);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoLineTo
+ (JNIEnv *env, jobject obj, jdouble x, jdouble y)
+{
+ struct cairographics2d *gr = getPointer (env, obj);
+ g_assert (gr != NULL);
+
+ cairo_line_to (gr->cr, x, y);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoCurveTo
+ (JNIEnv *env, jobject obj, jdouble x1, jdouble y1, jdouble x2, jdouble y2, jdouble x3, jdouble y3)
+{
+ struct cairographics2d *gr = getPointer (env, obj);
+ g_assert (gr != NULL);
+ cairo_curve_to (gr->cr, x1, y1, x2, y2, x3, y3);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoRelMoveTo
+ (JNIEnv *env, jobject obj, jdouble dx, jdouble dy)
+{
+ struct cairographics2d *gr = getPointer (env, obj);
+ g_assert (gr != NULL);
+
+ cairo_rel_move_to (gr->cr, dx, dy);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoRelLineTo
+ (JNIEnv *env, jobject obj, jdouble dx, jdouble dy)
+{
+ struct cairographics2d *gr = getPointer (env, obj);
+ g_assert (gr != NULL);
+
+ cairo_rel_line_to (gr->cr, dx, dy);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoRelCurveTo
+ (JNIEnv *env, jobject obj, jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2, jdouble dx3, jdouble dy3)
+{
+ struct cairographics2d *gr = getPointer (env, obj);
+ g_assert (gr != NULL);
+
+ cairo_rel_curve_to (gr->cr, dx1, dy1, dx2, dy2, dx3, dy3);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoRectangle
+ (JNIEnv *env, jobject obj, jdouble x, jdouble y, jdouble width, jdouble height)
+{
+ struct cairographics2d *gr = getPointer (env, obj);
+
+ cairo_rectangle (gr->cr, x, y, width, height);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoClosePath
+ (JNIEnv *env, jobject obj)
+{
+ struct cairographics2d *gr = getPointer (env, obj);
+ g_assert (gr != NULL);
+
+ cairo_close_path (gr->cr);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoStroke
+ (JNIEnv *env, jobject obj)
+{
+ struct cairographics2d *gr = getPointer (env, obj);
+ g_assert (gr != NULL);
+
+ cairo_stroke (gr->cr);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoFill
+ (JNIEnv *env, jobject obj)
+{
+ struct cairographics2d *gr = getPointer (env, obj);
+ g_assert (gr != NULL);
+
+ cairo_fill (gr->cr);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoClip
+ (JNIEnv *env, jobject obj)
+{
+ struct cairographics2d *gr = getPointer( env, obj );
+ g_assert( gr != NULL );
+
+ cairo_clip( gr->cr );
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoResetClip
+ (JNIEnv *env, jobject obj)
+{
+ struct cairographics2d *gr = getPointer( env, obj );
+ g_assert (gr != NULL);
+
+ cairo_reset_clip( gr->cr );
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoPreserveClip
+(JNIEnv *env, jobject obj)
+{
+ struct cairographics2d *gr = getPointer( env, obj );
+ g_assert (gr != NULL);
+
+ cairo_clip_preserve( gr->cr );
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSurfaceSetFilter
+ (JNIEnv *env, jobject obj, jint filter)
+{
+ struct cairographics2d *gr = getPointer (env, obj);
+ g_assert (gr != NULL);
+
+ if (gr->pattern == NULL)
+ return;
+
+ switch ((enum java_awt_rendering_hints_filter) filter)
+ {
+ case java_awt_rendering_hints_VALUE_INTERPOLATION_NEAREST_NEIGHBOR:
+ cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_NEAREST);
+ break;
+ case java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR:
+ cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_BILINEAR);
+ break;
+ case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED:
+ cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_FAST);
+ break;
+ case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT:
+ cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_NEAREST);
+ break;
+ case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY:
+ cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_BEST);
+ break;
+ }
+}
+
+/************************** FONT STUFF ****************************/
+static void
+install_font_peer(cairo_t *cr,
+ struct peerfont *pfont)
+{
+ cairo_font_face_t *ft;
+ FT_Face face = NULL;
+
+ g_assert(cr != NULL);
+ g_assert(pfont != NULL);
+
+ if (pfont->graphics_resource == NULL)
+ {
+ face = pango_ft2_font_get_face (pfont->font);
+ g_assert (face != NULL);
+
+ ft = cairo_ft_font_face_create_for_ft_face (face, 0);
+ g_assert (ft != NULL);
+
+ cairo_set_font_face (cr, ft);
+ cairo_font_face_destroy (ft);
+ cairo_set_font_size (cr,
+ (pango_font_description_get_size (pfont->desc) /
+ (double)PANGO_SCALE));
+ ft = cairo_get_font_face (cr);
+ pfont->graphics_resource = ft;
+ }
+ else
+ {
+ ft = (cairo_font_face_t *) pfont->graphics_resource;
+ cairo_set_font_face (cr, ft);
+ cairo_set_font_size (cr,
+ (pango_font_description_get_size (pfont->desc) /
+ (double)PANGO_SCALE));
+ }
+}
+
+static void
+update_pattern_transform (struct cairographics2d *gr)
+{
+ cairo_matrix_t mat;
+
+ g_assert (gr != NULL);
+ if (gr->pattern == NULL)
+ return;
+
+ cairo_get_matrix (gr->cr, &mat);
+ cairo_pattern_set_matrix (gr->pattern, &mat);
+}
+
+
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c
new file mode 100644
index 000000000..1a618cef5
--- /dev/null
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c
@@ -0,0 +1,311 @@
+/* gnu_java_awt_peer_gtk_CairoSurface.c
+ 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. */
+
+#include "jcl.h"
+#include "gtkpeer.h"
+#include <cairo-xlib.h>
+#include <gdk/gdkx.h>
+
+#include "gnu_java_awt_peer_gtk_CairoSurface.h"
+#include "cairographics2d.h"
+
+/**
+ * Field names in CairoSurface.java
+ */
+#define SURFACE "surfacePointer"
+#define BUFFER "bufferPointer"
+
+/* prototypes */
+static void *getNativeObject( JNIEnv *env, jobject obj, const char *pointer );
+static void setNativeObject( JNIEnv *env, jobject obj, void *ptr, const char *pointer );
+
+/**
+ * Creates a cairo surface, ARGB32, native ordering, premultiplied alpha.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoSurface_create (JNIEnv *env, jobject obj, jint width, jint height, jint stride)
+{
+ cairo_surface_t* surface;
+ void *data = g_malloc(stride * height * 4);
+ memset(data, 0, stride * height * 4);
+ setNativeObject(env, obj, data, BUFFER);
+
+ surface = cairo_image_surface_create_for_data
+ (data, CAIRO_FORMAT_ARGB32, width, height, stride);
+
+ setNativeObject(env, obj, surface, SURFACE);
+}
+
+/**
+ * Destroy the surface
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoSurface_destroy (JNIEnv *env, jobject obj)
+{
+ void *buffer;
+ cairo_surface_t* surface = (cairo_surface_t *)getNativeObject(env, obj, SURFACE);
+ if( surface != NULL )
+ cairo_surface_destroy(surface);
+
+ buffer = getNativeObject(env, obj, BUFFER);
+ if( buffer != NULL )
+ g_free(buffer);
+}
+
+/**
+ * Gets a pixel
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_awt_peer_gtk_CairoSurface_nativeGetElem (JNIEnv *env, jobject obj, jint i)
+{
+ jint *pixeldata = (jint *)getNativeObject(env, obj, BUFFER);
+
+ if( pixeldata == NULL )
+ return 0;
+
+ return pixeldata[i];
+}
+
+/**
+ * Sets a pixel
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoSurface_nativeSetElem
+(JNIEnv *env, jobject obj, jint i, jint val)
+{
+ jint *pixeldata = (jint *)getNativeObject(env, obj, BUFFER);
+
+ if( pixeldata == NULL )
+ return;
+
+ pixeldata[i] = val;
+}
+
+/**
+ * Gets all pixels in an array
+ */
+JNIEXPORT jintArray JNICALL
+Java_gnu_java_awt_peer_gtk_CairoSurface_getPixels
+(JNIEnv *env, jobject obj, int size)
+{
+ jint *pixeldata, *jpixdata;
+ jintArray jpixels;
+
+ pixeldata = (jint *)getNativeObject(env, obj, BUFFER);
+ g_assert(pixeldata != NULL);
+
+ jpixels = (*env)->NewIntArray (env, size);
+ jpixdata = (*env)->GetIntArrayElements (env, jpixels, NULL);
+ memcpy (jpixdata, pixeldata, size * sizeof( jint ));
+
+ (*env)->ReleaseIntArrayElements (env, jpixels, jpixdata, 0);
+ return jpixels;
+}
+
+/**
+ * Sets all pixels by an array.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoSurface_setPixels
+(JNIEnv *env, jobject obj, jintArray jpixels)
+{
+ jint *pixeldata, *jpixdata;
+ int size;
+ int width, height;
+ jclass cls;
+ jfieldID field;
+
+ if( jpixels == NULL )
+ return;
+
+ cls = (*env)->GetObjectClass (env, obj);
+ field = (*env)->GetFieldID (env, cls, "width", "I");
+ g_assert (field != 0);
+ width = (*env)->GetIntField (env, obj, field);
+
+ field = (*env)->GetFieldID (env, cls, "height", "I");
+ g_assert (field != 0);
+ height = (*env)->GetIntField (env, obj, field);
+
+ pixeldata = (jint *)getNativeObject(env, obj, BUFFER);
+ g_assert(pixeldata != NULL);
+
+ jpixdata = (*env)->GetIntArrayElements (env, jpixels, NULL);
+ size = (*env)->GetArrayLength( env, jpixels );
+ if( size > width * height ) size = width * height; /* stop overflows. */
+
+ memcpy (pixeldata, jpixdata, size * sizeof( jint ));
+
+ (*env)->ReleaseIntArrayElements (env, jpixels, jpixdata, 0);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoSurface_drawSurface
+ (JNIEnv *env, jobject obj, jobject context, jdoubleArray java_matrix)
+{
+ cairo_t *cr;
+ jdouble *native_matrix = NULL;
+ cairo_surface_t* surface = (cairo_surface_t *)getNativeObject(env, obj, SURFACE);
+ g_assert(surface != NULL);
+
+ cr = cp_gtk_get_cairo_t(env, context);
+ g_assert(cr != NULL);
+
+ native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL);
+ g_assert (native_matrix != NULL);
+ g_assert ((*env)->GetArrayLength (env, java_matrix) == 6);
+
+ {
+ cairo_matrix_t mat;
+ cairo_pattern_t *p;
+ cairo_matrix_init_identity (&mat);
+ cairo_matrix_init (&mat,
+ native_matrix[0], native_matrix[1],
+ native_matrix[2], native_matrix[3],
+ native_matrix[4], native_matrix[5]);
+
+ p = cairo_pattern_create_for_surface (surface);
+ cairo_pattern_set_matrix (p, &mat);
+
+ cairo_set_source(cr, p);
+ cairo_paint(cr);
+ }
+
+ (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0);
+}
+
+JNIEXPORT jlong JNICALL
+Java_gnu_java_awt_peer_gtk_CairoSurface_getFlippedBuffer
+(JNIEnv *env, jobject obj, jint size)
+{
+ jint *dst;
+ jint *src = (jint *)getNativeObject(env, obj, BUFFER);
+ int i;
+ int t;
+
+ g_assert( src != NULL );
+ dst = g_malloc( size * sizeof( jint ) );
+
+ for(i = 0; i < size; i++ )
+ {
+ t = (src[i] & 0x0000FF) << 16;
+ dst[i] = (src[i] & 0x00FF0000) >> 16;
+ dst[i] |= (src[i] & 0xFF00FF00);
+ dst[i] |= t;
+ }
+
+ return PTR_TO_JLONG(dst);
+}
+
+/**
+ * Create and return a cairo context for drawing to the surface.
+ */
+JNIEXPORT jlong JNICALL
+Java_gnu_java_awt_peer_gtk_CairoSurface_newCairoContext (JNIEnv *env, jobject obj)
+{
+ cairo_surface_t* surface = (cairo_surface_t *)getNativeObject(env, obj, SURFACE);
+ cairo_t *ptr;
+ g_assert(surface != NULL);
+ ptr = cairo_create(surface);
+ g_assert(ptr != NULL);
+
+ return PTR_TO_JLONG(ptr);
+}
+
+/**
+ * copyArea.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoSurface_copyAreaNative (JNIEnv *env,
+ jobject obj,
+ jint x, jint y,
+ jint w, jint h,
+ jint dx, jint dy,
+ jint stride)
+{
+ int row;
+ int srcOffset, dstOffset;
+ jint *temp;
+ jint *pixeldata = (jint *)getNativeObject(env, obj, BUFFER);
+ g_assert( pixeldata != NULL );
+
+ temp = g_malloc( h * w * 4 );
+ g_assert( temp != NULL );
+
+ srcOffset = x + (y * stride);
+ dstOffset = (x + dx) + ((y + dy) * stride);
+
+ for( row = 0; row < h; row++ )
+ memcpy( temp + (w * row), pixeldata + srcOffset + (stride * row), w * 4 );
+
+ for( row = 0; row < h; row++ )
+ memcpy( pixeldata + dstOffset + (stride * row), temp + (w * row), w * 4 );
+
+ g_free( temp );
+}
+
+/*
+ * Sets the native object field.
+ */
+static void
+setNativeObject( JNIEnv *env, jobject obj, void *ptr, const char *pointer )
+{
+ jclass cls;
+ jlong value;
+ jfieldID nofid;
+ cls = (*env)->GetObjectClass( env, obj );
+ value = PTR_TO_JLONG(ptr);
+ nofid = (*env)->GetFieldID( env, cls, pointer, "J" );
+ (*env)->SetLongField( env, obj, nofid, value );
+ (*env)->DeleteLocalRef( env, cls );
+}
+
+/**
+ * Gets the native object field.
+ */
+static void *
+getNativeObject( JNIEnv *env, jobject obj, const char *pointer )
+{
+ jclass cls;
+ jlong value;
+ jfieldID nofid;
+ cls = (*env)->GetObjectClass( env, obj );
+ nofid = (*env)->GetFieldID( env, cls, pointer, "J" );
+ value = (*env)->GetLongField( env, obj, nofid );
+ (*env)->DeleteLocalRef( env, cls );
+ return JLONG_TO_PTR(void, value);
+}
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphics.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphics.c
new file mode 100644
index 000000000..eea219569
--- /dev/null
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphics.c
@@ -0,0 +1,243 @@
+/* gnu_java_awt_peer_gtk_ComponentGraphics.c
+ 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. */
+
+#include "jcl.h"
+#include "gtkpeer.h"
+#include <cairo-xlib.h>
+#include <gdk/gdktypes.h>
+#include <gdk/gdkprivate.h>
+#include <gdk/gdkx.h>
+#include <X11/extensions/Xrender.h>
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gdk-pixbuf/gdk-pixdata.h>
+
+#include <cairo-ft.h>
+#include <cairo-xlib.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "gnu_java_awt_peer_gtk_ComponentGraphics.h"
+
+static short flush_scheduled = 0;
+
+static gboolean flush (gpointer data __attribute__((unused)))
+{
+ gdk_threads_enter ();
+
+ XFlush (GDK_DISPLAY ());
+ flush_scheduled = 0;
+
+ gdk_threads_leave ();
+
+ return FALSE;
+}
+
+/* The minimum time period between calls to XFlush, in
+ milliseconds. */
+#define MINIMUM_FLUSH_PERIOD 20
+
+/* schedule_flush must be called with the GDK lock held. */
+static void
+schedule_flush ()
+{
+ if (!flush_scheduled)
+ {
+ g_timeout_add (MINIMUM_FLUSH_PERIOD, flush, NULL);
+ flush_scheduled = 1;
+ }
+}
+
+void cp_gtk_grab_current_drawable(GtkWidget *widget, GdkDrawable **draw,
+ GdkWindow **win)
+{
+ g_assert (widget != NULL);
+ g_assert (draw != NULL);
+ g_assert (win != NULL);
+
+ *win = widget->window;
+
+ *draw = *win;
+ gdk_window_get_internal_paint_info (*win, draw, 0, 0);
+}
+
+/**
+ * Returns whether the XRender extension is supported
+ */
+JNIEXPORT jboolean JNICALL
+Java_gnu_java_awt_peer_gtk_ComponentGraphics_hasXRender
+ (JNIEnv *env __attribute__ ((unused)), jclass cls __attribute__ ((unused)))
+{
+#if HAVE_XRENDER
+ int ev = 0, err = 0;
+ if( XRenderQueryExtension (GDK_DISPLAY (), &ev, &err) )
+ return JNI_TRUE;
+#endif
+ return JNI_FALSE;
+}
+
+
+JNIEXPORT jlong JNICALL
+Java_gnu_java_awt_peer_gtk_ComponentGraphics_initState
+ (JNIEnv *env, jobject obj __attribute__ ((unused)), jobject peer)
+{
+ Drawable draw;
+ Display * dpy;
+ Visual * vis;
+ GdkDrawable *drawable;
+ cairo_surface_t *surface;
+ GdkWindow *win;
+ GtkWidget *widget = NULL;
+ void *ptr = NULL;
+ int width, height;
+ cairo_t *cr;
+
+ gdk_threads_enter();
+
+ ptr = NSA_GET_PTR (env, peer);
+ g_assert (ptr != NULL);
+
+ widget = GTK_WIDGET (ptr);
+ g_assert (widget != NULL);
+
+ cp_gtk_grab_current_drawable (widget, &drawable, &win);
+ g_assert (drawable != NULL);
+
+ width = widget->allocation.width;
+ height = widget->allocation.height;
+
+ g_assert (drawable != NULL);
+
+ draw = gdk_x11_drawable_get_xid(drawable);
+ g_assert (draw != (XID) 0);
+
+ dpy = gdk_x11_drawable_get_xdisplay(drawable);
+ g_assert (dpy != NULL);
+
+ vis = gdk_x11_visual_get_xvisual(gdk_drawable_get_visual(drawable));
+ g_assert (vis != NULL);
+
+ surface = cairo_xlib_surface_create (dpy, draw, vis, width, height);
+ g_assert (surface != NULL);
+
+ cr = cairo_create (surface);
+ g_assert(cr != NULL);
+
+ gdk_threads_leave();
+
+ return PTR_TO_JLONG(cr);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_ComponentGraphics_start_1gdk_1drawing
+ (JNIEnv *env __attribute__ ((unused)), jobject obj __attribute__ ((unused)))
+{
+ gdk_threads_enter();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_ComponentGraphics_end_1gdk_1drawing
+ (JNIEnv *env __attribute__ ((unused)), jobject obj __attribute__ ((unused)))
+{
+ schedule_flush ();
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_ComponentGraphics_copyAreaNative
+ (JNIEnv *env, jobject obj __attribute__((unused)), jobject peer,
+ jint x, jint y, jint w, jint h, jint dx, jint dy)
+{
+ GdkPixbuf *pixbuf;
+ GdkDrawable *drawable;
+ GdkWindow *win;
+ GtkWidget *widget = NULL;
+ void *ptr = NULL;
+
+ gdk_threads_enter();
+
+ ptr = NSA_GET_PTR (env, peer);
+ g_assert (ptr != NULL);
+
+ widget = GTK_WIDGET (ptr);
+ g_assert (widget != NULL);
+
+ cp_gtk_grab_current_drawable (widget, &drawable, &win);
+ g_assert (drawable != NULL);
+
+ pixbuf = gdk_pixbuf_new( GDK_COLORSPACE_RGB, TRUE, 8, w, h );
+ gdk_pixbuf_get_from_drawable( pixbuf, drawable, NULL, x, y, 0, 0, w, h );
+ gdk_draw_pixbuf (drawable, NULL, pixbuf,
+ 0, 0, x + dx, y + dy,
+ w, h,
+ GDK_RGB_DITHER_NORMAL, 0, 0);
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_ComponentGraphics_drawVolatile
+(JNIEnv *env, jobject obj __attribute__ ((unused)), jobject peer,
+ jobject img, jint x, jint y, jint w, jint h)
+{
+ GdkPixmap *pixmap;
+ GtkWidget *widget = NULL;
+ void *ptr = NULL;
+ GdkGC *gc;
+
+ gdk_threads_enter();
+
+ ptr = NSA_GET_PTR (env, peer);
+ g_assert (ptr != NULL);
+
+ widget = GTK_WIDGET (ptr);
+ g_assert (widget != NULL);
+
+ pixmap = cp_gtk_get_pixmap( env, img );
+
+ gc = gdk_gc_new(GDK_DRAWABLE(widget->window));
+ gdk_draw_drawable(GDK_DRAWABLE(widget->window),
+ gc,
+ pixmap,
+ 0, 0,
+ x, y,
+ w, h);
+
+ schedule_flush ();
+
+ gdk_threads_leave();
+}
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphicsCopy.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphicsCopy.c
new file mode 100644
index 000000000..76caa5d0c
--- /dev/null
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphicsCopy.c
@@ -0,0 +1,132 @@
+/* gnu_java_awt_peer_gtk_ComponentGraphicsCopy.c
+ 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. */
+
+#include "jcl.h"
+#include "gtkpeer.h"
+#include <cairo-xlib.h>
+#include <gdk/gdktypes.h>
+#include <gdk/gdkprivate.h>
+#include <gdk/gdkx.h>
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gdk-pixbuf/gdk-pixdata.h>
+
+#include <cairo-ft.h>
+#include <cairo-xlib.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "gnu_java_awt_peer_gtk_ComponentGraphicsCopy.h"
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_ComponentGraphicsCopy_getPixbuf
+ (JNIEnv *env, jobject obj __attribute__((unused)),
+ jobject peer, jobject image)
+{
+ gint width, height;
+ GdkPixbuf *pixbuf;
+ GdkDrawable *drawable;
+ GdkWindow *win;
+ GtkWidget *widget = NULL;
+ void *ptr = NULL;
+
+ gdk_threads_enter();
+
+ ptr = NSA_GET_PTR (env, peer);
+ g_assert (ptr != NULL);
+
+ widget = GTK_WIDGET (ptr);
+ g_assert (widget != NULL);
+
+ cp_gtk_grab_current_drawable (widget, &drawable, &win);
+ g_assert (drawable != NULL);
+
+ pixbuf = cp_gtk_image_get_pixbuf( env, image );
+ g_assert( pixbuf != NULL);
+
+ width = gdk_pixbuf_get_width( pixbuf );
+ height = gdk_pixbuf_get_height( pixbuf );
+
+ gdk_pixbuf_get_from_drawable( pixbuf, /* destination pixbuf */
+ drawable,
+ NULL, /* colormap */
+ 0, 0, 0, 0,
+ width, height );
+ gdk_threads_leave();
+}
+
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_ComponentGraphicsCopy_copyPixbuf
+ (JNIEnv *env, jobject obj __attribute__((unused)),
+ jobject peer, jobject image,
+ int x __attribute__((unused)), int y __attribute__((unused)),
+ int width __attribute__((unused)), int height __attribute__((unused)))
+{
+ gint pwidth, pheight;
+ GdkPixbuf *pixbuf;
+ GdkDrawable *drawable;
+ GdkWindow *win;
+ GtkWidget *widget = NULL;
+ void *ptr = NULL;
+
+ gdk_threads_enter();
+
+ ptr = NSA_GET_PTR (env, peer);
+ g_assert (ptr != NULL);
+
+ widget = GTK_WIDGET (ptr);
+ g_assert (widget != NULL);
+
+ cp_gtk_grab_current_drawable (widget, &drawable, &win);
+ g_assert (drawable != NULL);
+
+ pixbuf = cp_gtk_image_get_pixbuf( env, image );
+ g_assert( pixbuf != NULL);
+
+ pwidth = gdk_pixbuf_get_width( pixbuf );
+ pheight = gdk_pixbuf_get_height( pixbuf );
+
+ gdk_draw_pixbuf (drawable, NULL, pixbuf,
+ 0, 0, 0, 0,
+ pwidth, pheight,
+ GDK_RGB_DITHER_NORMAL, 0, 0);
+
+ gdk_threads_leave();
+}
+
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c
index 0726fb531..8b5609141 100644
--- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c
@@ -35,6 +35,13 @@
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
+#include <pango/pango.h>
+#include <pango/pangoft2.h>
+#include <pango/pangofc-font.h>
+#include <freetype/ftglyph.h>
+#include <freetype/ftoutln.h>
+#include <freetype/fttypes.h>
+#include <freetype/tttables.h>
#include "gdkfont.h"
#include "gnu_java_awt_peer_gtk_GdkFontPeer.h"
@@ -114,6 +121,25 @@ Java_gnu_java_awt_peer_gtk_GdkFontPeer_dispose
}
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkFontPeer_releasePeerGraphicsResource
+ (JNIEnv *env, jobject java_font)
+{
+ struct peerfont *pfont = NULL;
+
+ gdk_threads_enter();
+
+ pfont = (struct peerfont *) NSA_GET_FONT_PTR (env, java_font);
+ g_assert (pfont != NULL);
+ if (pfont->graphics_resource != NULL)
+ {
+ cairo_font_face_destroy ((cairo_font_face_t *) pfont->graphics_resource);
+ pfont->graphics_resource = NULL;
+ }
+
+ gdk_threads_leave();
+}
+
JNIEXPORT jobject JNICALL
Java_gnu_java_awt_peer_gtk_GdkFontPeer_getGlyphVector
(JNIEnv *env, jobject self,
@@ -389,7 +415,7 @@ Java_gnu_java_awt_peer_gtk_GdkFontPeer_getTextMetrics
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkFontPeer_setFont
- (JNIEnv *env, jobject self, jstring family_name_str, jint style_int, jint size, jboolean useGraphics2D)
+ (JNIEnv *env, jobject self, jstring family_name_str, jint style_int, jint size)
{
struct peerfont *pfont = NULL;
char const *family_name = NULL;
@@ -426,22 +452,11 @@ Java_gnu_java_awt_peer_gtk_GdkFontPeer_setFont
if (style & java_awt_font_ITALIC)
pango_font_description_set_style (pfont->desc, PANGO_STYLE_ITALIC);
- if (useGraphics2D)
- {
- pango_font_description_set_size (pfont->desc, size * PANGO_SCALE);
- if (pfont->ctx == NULL)
- {
- ft2_map = PANGO_FT2_FONT_MAP(pango_ft2_font_map_for_display ());
- pfont->ctx = pango_ft2_font_map_create_context (ft2_map);
- }
- }
- else
+ pango_font_description_set_size (pfont->desc, size * PANGO_SCALE);
+ if (pfont->ctx == NULL)
{
- /* GDK uses a slightly different DPI setting. */
- pango_font_description_set_size (pfont->desc,
- size * cp_gtk_dpi_conversion_factor);
- if (pfont->ctx == NULL)
- pfont->ctx = gdk_pango_context_get();
+ ft2_map = PANGO_FT2_FONT_MAP(pango_ft2_font_map_for_display ());
+ pfont->ctx = pango_ft2_font_map_create_context (ft2_map);
}
g_assert (pfont->ctx != NULL);
@@ -465,3 +480,64 @@ Java_gnu_java_awt_peer_gtk_GdkFontPeer_setFont
}
+JNIEXPORT jbyteArray JNICALL
+Java_gnu_java_awt_peer_gtk_GdkFontPeer_getTrueTypeTable
+ (JNIEnv *env, jobject self, jbyte n, jbyte a, jbyte m, jbyte e)
+{
+ struct peerfont *pfont = NULL;
+ FT_Face face;
+ FT_ULong length = 0;
+ FT_ULong tag;
+ int error;
+ FT_Byte *buffer;
+ jbyteArray result_array;
+ jbyte *rbuf;
+
+ pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, self);
+ if(pfont == NULL)
+ return NULL;
+
+ gdk_threads_enter ();
+ face = pango_fc_font_lock_face ((PangoFcFont *)pfont->font);
+ tag = FT_MAKE_TAG( n, a, m, e );
+
+ /* Get the length of the table requested */
+ error = FT_Load_Sfnt_Table( face, tag, 0, NULL, &length );
+ if ( error )
+ {
+ pango_fc_font_unlock_face ((PangoFcFont *)pfont->font);
+ gdk_threads_leave ();
+ return NULL;
+ }
+
+ buffer = (FT_Byte *)g_malloc0( length );
+ if ( buffer == NULL )
+ {
+ pango_fc_font_unlock_face ((PangoFcFont *)pfont->font);
+ gdk_threads_leave ();
+ return NULL;
+ }
+ /* get the table data */
+ error = FT_Load_Sfnt_Table( face, tag, 0, buffer, &length );
+ if ( error )
+ {
+ pango_fc_font_unlock_face ((PangoFcFont *)pfont->font);
+ g_free(buffer);
+ gdk_threads_leave ();
+ return NULL;
+ }
+
+ /* copy to a jbytearray */
+ result_array = (*env)->NewByteArray (env, length);
+
+ rbuf = (*env)->GetByteArrayElements (env, result_array, NULL);
+ memcpy(rbuf, buffer, length);
+ (*env)->ReleaseByteArrayElements (env, result_array, rbuf, 0);
+
+ g_free(buffer);
+ pango_fc_font_unlock_face ((PangoFcFont *)pfont->font);
+ gdk_threads_leave ();
+
+ /* done */
+ return result_array;
+}
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c
deleted file mode 100644
index 29bc1855b..000000000
--- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c
+++ /dev/null
@@ -1,758 +0,0 @@
-/* gdkgraphics.c
- Copyright (C) 1999 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. */
-
-#include "gtkpeer.h"
-#include "gdkfont.h"
-#include "gnu_java_awt_peer_gtk_GdkGraphics.h"
-#include <gdk/gdkprivate.h>
-#include <gdk/gdkx.h>
-
-static jmethodID initComponentGraphicsUnlockedID;
-
-/*
- * AWT applications may call Graphics methods from threads other than
- * the GDK main thread, so we must call XFlush after each batch of
- * drawing operations, otherwise animations flicker. Flushing after
- * every graphics operation is excessive and negatively affects
- * performance (PR 26486). We set the maximum frequency to 50 times
- * per second, or a minimum period of 20 milliseconds between calls to
- * XFlush. See gnu.classpath.examples.awt.AnimationApplet for an
- * example applet that requires these XFlush calls.
- */
-
-static short flush_scheduled = 0;
-
-static gboolean flush (gpointer data __attribute__((unused)))
-{
- gdk_threads_enter ();
-
- XFlush (GDK_DISPLAY ());
- flush_scheduled = 0;
-
- gdk_threads_leave ();
-
- return FALSE;
-}
-
-/* The minimum time period between calls to XFlush, in
- milliseconds. */
-#define MINIMUM_FLUSH_PERIOD 20
-
-/* schedule_flush must be called with the GDK lock held. */
-static void
-schedule_flush ()
-{
- if (!flush_scheduled)
- {
- g_timeout_add (MINIMUM_FLUSH_PERIOD, flush, NULL);
- flush_scheduled = 1;
- }
-}
-
-void
-cp_gtk_graphics_init_jni (void)
-{
- jclass gdkgraphics;
-
- gdkgraphics = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
- "gnu/java/awt/peer/gtk/GdkGraphics");
-
- initComponentGraphicsUnlockedID =
- (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gdkgraphics,
- "initComponentGraphicsUnlocked",
- "()V");
-}
-
-struct state_table *cp_gtk_native_graphics_state_table;
-
-static struct state_table *native_graphics_global_ref_table;
-
-#define NSA_GLOBAL_G_INIT(env, clazz) \
- native_graphics_global_ref_table = cp_gtk_init_state_table (env, clazz)
-
-#define NSA_GET_GLOBAL_G_REF(env, obj) \
- cp_gtk_get_state (env, obj, native_graphics_global_ref_table)
-
-#define NSA_SET_GLOBAL_G_REF(env, obj) \
- do {jobject *globRefPtr; \
- globRefPtr = (jobject *) malloc (sizeof (jobject)); \
- *globRefPtr = (*env)->NewGlobalRef (env, obj); \
- cp_gtk_set_state (env, obj, native_graphics_global_ref_table, (void *)globRefPtr);} while (0)
-
-#define NSA_DEL_GLOBAL_G_REF(env, obj) \
- do {jobject *globRefPtr = cp_gtk_get_state (env, obj, native_graphics_global_ref_table); \
- cp_gtk_remove_state_slot (env, obj, native_graphics_global_ref_table); \
- (*env)->DeleteGlobalRef (env, *globRefPtr); \
- free (globRefPtr);} while (0)
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics_initStaticState
- (JNIEnv *env, jclass clazz)
-{
- gdk_threads_enter();
-
- NSA_G_INIT (env, clazz);
- NSA_GLOBAL_G_INIT (env, clazz);
-
- gdk_threads_leave();
-}
-
-#define GDK_STABLE_IS_PIXMAP(d) (GDK_IS_PIXMAP(d))
-
-static GdkPoint *translate_points (JNIEnv *env, jintArray xpoints,
- jintArray ypoints, jint npoints,
- jint x_offset, jint y_offset);
-static void realize_cb (GtkWidget *widget, jobject jgraphics);
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics_nativeCopyState
- (JNIEnv *env, jobject obj, jobject old)
-{
- struct graphics *g = NULL;
- struct graphics *g_old = NULL;
-
- gdk_threads_enter ();
-
- g = (struct graphics *) g_malloc (sizeof (struct graphics));
- g_old = (struct graphics *) NSA_GET_G_PTR (env, old);
-
- *g = *g_old;
-
- g->gc = gdk_gc_new (g->drawable);
- gdk_gc_copy (g->gc, g_old->gc);
-
- if (GDK_STABLE_IS_PIXMAP (g->drawable))
- g_object_ref (g->drawable);
- else /* GDK_IS_WINDOW (g->drawable) */
- g_object_ref (g->drawable);
-
- if (g->cm != NULL)
- g_object_ref (g->cm);
-
- NSA_SET_G_PTR (env, obj, g);
-
- gdk_threads_leave ();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics_initState__II
- (JNIEnv *env, jobject obj, jint width, jint height)
-{
- struct graphics *g = NULL;
-
- gdk_threads_enter ();
-
- g = (struct graphics *) g_malloc (sizeof (struct graphics));
- g->x_offset = g->y_offset = 0;
-
- g->drawable = (GdkDrawable *) gdk_pixmap_new (NULL, width, height,
- gdk_rgb_get_visual ()->depth);
- g->cm = gdk_rgb_get_colormap ();
-
- if (g->cm != NULL)
- g_object_ref (g->cm);
- g->gc = gdk_gc_new (g->drawable);
-
- NSA_SET_G_PTR (env, obj, g);
-
- gdk_threads_leave ();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics_initFromImage
- (JNIEnv *env, jobject obj, jobject source)
-{
- struct graphics *g = NULL;
- GdkPixmap *pixmap = NULL;
-
- gdk_threads_enter ();
-
- pixmap = cp_gtk_image_get_pixmap (env, source);
- g_assert(pixmap != NULL);
- g_object_ref (pixmap);
-
- g = (struct graphics *) g_malloc (sizeof (struct graphics));
- g->x_offset = g->y_offset = 0;
-
- g->drawable = (GdkDrawable *)pixmap;
-
- g->cm = gdk_drawable_get_colormap (g->drawable);
-
- if (g->cm != NULL)
- g_object_ref (g->cm);
- g->gc = gdk_gc_new (g->drawable);
-
- NSA_SET_G_PTR (env, obj, g);
-
- gdk_threads_leave ();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics_initStateUnlocked
- (JNIEnv *env, jobject obj, jobject peer)
-{
- struct graphics *g = NULL;
- void *ptr = NULL;
- GtkWidget *widget = NULL;
- GdkColor color;
-
- g = (struct graphics *) g_malloc (sizeof (struct graphics));
- ptr = NSA_GET_PTR (env, peer);
- g->x_offset = 0;
- g->y_offset = 0;
-
- widget = GTK_WIDGET (ptr);
- g->drawable = (GdkDrawable *) widget->window;
-
- g_object_ref (g->drawable);
- g->cm = gtk_widget_get_colormap (widget);
-
- if (g->cm != NULL)
- g_object_ref (g->cm);
-
- g->gc = gdk_gc_new (g->drawable);
- gdk_gc_copy (g->gc, widget->style->fg_gc[GTK_STATE_NORMAL]);
- color = widget->style->fg[GTK_STATE_NORMAL];
-
- NSA_SET_G_PTR (env, obj, g);
-}
-
-/* copy the native state of the peer (GtkWidget *) to the native state
- of the graphics object */
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics_initState__Lgnu_java_awt_peer_gtk_GtkComponentPeer_2
- (JNIEnv *env, jobject obj, jobject peer)
-{
- gdk_threads_enter ();
- Java_gnu_java_awt_peer_gtk_GdkGraphics_initStateUnlocked
- (env, obj, peer);
- gdk_threads_leave ();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics_connectSignals
- (JNIEnv *env, jobject obj, jobject peer)
-{
- void *ptr = NULL;
- jobject *gref = NULL;
-
- gdk_threads_enter ();
-
- NSA_SET_GLOBAL_G_REF (env, obj);
- gref = NSA_GET_GLOBAL_G_REF (env, obj);
-
- ptr = NSA_GET_PTR (env, peer);
-
- g_signal_connect_after (G_OBJECT (ptr), "realize",
- G_CALLBACK (realize_cb), *gref);
-
- gdk_threads_leave ();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics_nativeDispose
- (JNIEnv *env, jobject obj)
-{
- struct graphics *g = NULL;
-
- gdk_threads_enter ();
-
- g = (struct graphics *) NSA_DEL_G_PTR (env, obj);
-
- /* check if dispose has been called already */
- if (!g)
- {
- gdk_threads_leave ();
- return;
- }
-
- XFlush (GDK_DISPLAY ());
-
- if (g->gc != NULL)
- g_object_unref (g->gc);
-
- if (GDK_STABLE_IS_PIXMAP (g->drawable))
- g_object_unref (g->drawable);
- else if (g->drawable != NULL)
- g_object_unref (g->drawable);
-
- if (g->cm != NULL)
- g_object_unref (g->cm);
-
- g_free (g);
-
- gdk_threads_leave ();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics_translateNative
- (JNIEnv *env, jobject obj, jint x, jint y)
-{
- struct graphics *g = NULL;
-
- gdk_threads_enter ();
-
- g = (struct graphics *) NSA_GET_G_PTR (env, obj);
-
- g->x_offset += x;
- g->y_offset += y;
-
- gdk_threads_leave ();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics_drawString
- (JNIEnv *env, jobject obj, jobject font, jstring str, jint x, jint y)
-{
- struct peerfont *pfont = NULL;
- struct graphics *g = NULL;
- const char *cstr = NULL;
- const char *sTmp = NULL;
- char *tmp = NULL;
- char *p = NULL;
- int count = 0;
- int charSize = 0;
- int baseline_y = 0;
- PangoLayoutIter *iter = NULL;
-
- gdk_threads_enter ();
-
- g = (struct graphics *) NSA_GET_G_PTR (env, obj);
- g_assert (g != NULL);
-
- pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, font);
- g_assert (pfont != NULL);
-
- cstr = (*env)->GetStringUTFChars (env, str, NULL);
- g_assert (cstr != NULL);
-
- charSize = sizeof(char);
- p = malloc((strlen(cstr) + 1) * charSize);
- g_assert (p != NULL);
-
- tmp = p;
- sTmp = cstr;
- for (; *sTmp != '\0'; sTmp++)
- if (((unsigned char) *sTmp) >= ' ')
- {
- *p = *sTmp;
- count++;
- p++;
- }
- *p = '\0';
-
- p = realloc(tmp, (count + 1) * charSize);
- g_assert (p != NULL);
- pango_layout_set_text (pfont->layout, p, -1);
- free(p);
-
- pango_layout_set_font_description (pfont->layout, pfont->desc);
- iter = pango_layout_get_iter (pfont->layout);
-
- baseline_y = pango_layout_iter_get_baseline (iter);
-
- gdk_draw_layout (g->drawable, g->gc,
- x + g->x_offset,
- y + g->y_offset - PANGO_PIXELS (baseline_y),
- pfont->layout);
-
- pango_layout_iter_free (iter);
- pango_layout_set_text (pfont->layout, "", -1);
-
- schedule_flush ();
-
- (*env)->ReleaseStringUTFChars (env, str, cstr);
-
- gdk_threads_leave ();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics_drawLine
- (JNIEnv *env, jobject obj, jint x, jint y, jint x2, jint y2)
-{
- struct graphics *g = NULL;
-
- gdk_threads_enter ();
-
- g = (struct graphics *) NSA_GET_G_PTR (env, obj);
-
- gdk_draw_line (g->drawable, g->gc,
- x + g->x_offset, y + g->y_offset,
- x2 + g->x_offset, y2 + g->y_offset);
- schedule_flush ();
-
- gdk_threads_leave ();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics_fillRect
- (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
-{
- struct graphics *g = NULL;
-
- gdk_threads_enter ();
-
- g = (struct graphics *) NSA_GET_G_PTR (env, obj);
-
- gdk_draw_rectangle (g->drawable, g->gc, TRUE,
- x + g->x_offset, y + g->y_offset, width, height);
- schedule_flush ();
-
- gdk_threads_leave ();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics_drawRect
- (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
-{
- struct graphics *g = NULL;
-
- gdk_threads_enter ();
-
- g = (struct graphics *) NSA_GET_G_PTR (env, obj);
-
- gdk_draw_rectangle (g->drawable, g->gc, FALSE,
- x + g->x_offset, y + g->y_offset, width, height);
- schedule_flush ();
-
- gdk_threads_leave ();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics_copyArea
- (JNIEnv *env, jobject obj, jint x, jint y,
- jint width, jint height, jint dx, jint dy)
-{
- struct graphics *g = NULL;
-
- gdk_threads_enter ();
-
- g = (struct graphics *) NSA_GET_G_PTR (env, obj);
-
- gdk_draw_drawable ((GdkWindow *)g->drawable,
- g->gc,
- (GdkWindow *)g->drawable,
- x + g->x_offset, y + g->y_offset,
- x + g->x_offset + dx, y + g->y_offset + dy,
- width, height);
- schedule_flush ();
-
- gdk_threads_leave ();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics_clearRect
- (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
-{
- struct graphics *g = NULL;
- GdkGCValues saved;
- GtkWidget *widget = NULL;
- union widget_union w;
-
- gdk_threads_enter ();
-
- g = (struct graphics *) NSA_GET_G_PTR (env, obj);
-
- if (!g)
- {
- gdk_threads_leave ();
- return;
- }
-
- if (GDK_IS_WINDOW (g->drawable))
- {
- w.widget = &widget;
- gdk_window_get_user_data (GDK_WINDOW (g->drawable), w.void_widget);
- if (widget == NULL || !GTK_IS_EVENT_BOX (widget))
- gdk_window_clear_area ((GdkWindow *) g->drawable,
- x + g->x_offset, y + g->y_offset,
- width, height);
- }
- else
- {
- gdk_gc_get_values (g->gc, &saved);
- gdk_gc_set_background (g->gc, &(saved.background));
- gdk_draw_rectangle (g->drawable, g->gc, TRUE,
- x + g->x_offset, y + g->y_offset, width, height);
- gdk_gc_set_foreground (g->gc, &(saved.foreground));
- }
-
- schedule_flush ();
-
- gdk_threads_leave ();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics_setFunction
- (JNIEnv *env, jobject obj, jint func)
-{
- struct graphics *g = NULL;
-
- gdk_threads_enter ();
-
- g = (struct graphics *) NSA_GET_G_PTR (env, obj);
-
- gdk_gc_set_function (g->gc, func);
-
- gdk_threads_leave ();
-}
-
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics_setFGColor
- (JNIEnv *env, jobject obj, jint red, jint green, jint blue)
-{
- GdkColor color;
- struct graphics *g = NULL;
-
- gdk_threads_enter ();
-
- color.red = red << 8;
- color.green = green << 8;
- color.blue = blue << 8;
-
- g = (struct graphics *) NSA_GET_G_PTR (env, obj);
-
- if (g->cm != NULL)
- gdk_colormap_alloc_color (g->cm, &color, TRUE, TRUE);
-
- gdk_gc_set_foreground (g->gc, &color);
-
- gdk_threads_leave ();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics_drawArc
- (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height,
- jint angle1, jint angle2)
-{
- struct graphics *g = NULL;
-
- gdk_threads_enter ();
-
- g = (struct graphics *) NSA_GET_G_PTR (env, obj);
-
- gdk_draw_arc (g->drawable, g->gc, FALSE,
- x + g->x_offset, y + g->y_offset,
- width, height, angle1 << 6, angle2 << 6);
- schedule_flush ();
-
- gdk_threads_leave ();
-}
-
-static GdkPoint *
-translate_points (JNIEnv *env, jintArray xpoints, jintArray ypoints,
- jint npoints, jint x_offset, jint y_offset)
-{
- GdkPoint *points;
- jint *x, *y;
- int i;
-
- /* allocate one more point than necessary, in case we need to tack
- on an extra due to the semantics of Java polygons. */
- points = g_malloc (sizeof (GdkPoint) * (npoints + 1));
-
- x = (*env)->GetIntArrayElements (env, xpoints, NULL);
- y = (*env)->GetIntArrayElements (env, ypoints, NULL);
-
- for (i = 0; i < npoints; i++)
- {
- points[i].x = x[i] + x_offset;
- points[i].y = y[i] + y_offset;
- }
-
- (*env)->ReleaseIntArrayElements (env, xpoints, x, JNI_ABORT);
- (*env)->ReleaseIntArrayElements (env, ypoints, y, JNI_ABORT);
-
- return points;
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics_drawPolyline
- (JNIEnv *env, jobject obj, jintArray xpoints, jintArray ypoints,
- jint npoints)
-{
- struct graphics *g = NULL;
- GdkPoint *points = NULL;
-
- gdk_threads_enter ();
-
- g = (struct graphics *) NSA_GET_G_PTR (env, obj);
- points = translate_points (env, xpoints, ypoints, npoints,
- g->x_offset, g->y_offset);
-
- gdk_draw_lines (g->drawable, g->gc, points, npoints);
- schedule_flush ();
-
- g_free (points);
-
- gdk_threads_leave ();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics_drawPolygon
- (JNIEnv *env, jobject obj, jintArray xpoints, jintArray ypoints,
- jint npoints)
-{
- struct graphics *g = NULL;
- GdkPoint *points = NULL;
-
- gdk_threads_enter ();
-
- g = (struct graphics *) NSA_GET_G_PTR (env, obj);
- points = translate_points (env, xpoints, ypoints, npoints,
- g->x_offset, g->y_offset);
-
- /* make sure the polygon is closed, per Java semantics.
- if it's not, we close it. */
- if (points[0].x != points[npoints-1].x || points[0].y != points[npoints-1].y)
- points[npoints++] = points[0];
-
- gdk_draw_lines (g->drawable, g->gc, points, npoints);
- schedule_flush ();
-
- g_free (points);
-
- gdk_threads_leave ();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics_fillPolygon
- (JNIEnv *env, jobject obj, jintArray xpoints, jintArray ypoints,
- jint npoints)
-{
- struct graphics *g = NULL;
- GdkPoint *points = NULL;
-
- gdk_threads_enter ();
-
- g = (struct graphics *) NSA_GET_G_PTR (env, obj);
- points = translate_points (env, xpoints, ypoints, npoints,
- g->x_offset, g->y_offset);
- gdk_draw_polygon (g->drawable, g->gc, TRUE, points, npoints);
- schedule_flush ();
-
- g_free (points);
-
- gdk_threads_leave ();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics_fillArc
- (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height,
- jint angle1, jint angle2)
-{
- struct graphics *g = NULL;
-
- gdk_threads_enter ();
-
- g = (struct graphics *) NSA_GET_G_PTR (env, obj);
-
- gdk_draw_arc (g->drawable, g->gc, TRUE,
- x + g->x_offset, y + g->y_offset,
- width, height, angle1 << 6, angle2 << 6);
- schedule_flush ();
-
- gdk_threads_leave ();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics_drawOval
- (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
-{
- struct graphics *g = NULL;
-
- gdk_threads_enter ();
-
- g = (struct graphics *) NSA_GET_G_PTR (env, obj);
-
- gdk_draw_arc (g->drawable, g->gc, FALSE,
- x + g->x_offset, y + g->y_offset,
- width, height, 0, 23040);
- schedule_flush ();
-
- gdk_threads_leave ();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics_fillOval
- (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
-{
- struct graphics *g = NULL;
-
- gdk_threads_enter ();
-
- g = (struct graphics *) NSA_GET_G_PTR (env, obj);
-
- gdk_draw_arc (g->drawable, g->gc, TRUE,
- x + g->x_offset, y + g->y_offset,
- width, height, 0, 23040);
- schedule_flush ();
-
- gdk_threads_leave ();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics_setClipRectangle
- (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
-{
- struct graphics *g = NULL;
- GdkRectangle rectangle;
-
- gdk_threads_enter ();
-
- g = (struct graphics *) NSA_GET_G_PTR (env, obj);
-
- rectangle.x = x + g->x_offset;
- rectangle.y = y + g->y_offset;
- rectangle.width = width;
- rectangle.height = height;
-
- gdk_gc_set_clip_rectangle (g->gc, &rectangle);
-
- gdk_threads_leave ();
-}
-
-static void
-realize_cb (GtkWidget *widget __attribute__ ((unused)), jobject jgraphics)
-{
- (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(),
- jgraphics,
- initComponentGraphicsUnlockedID);
-
- NSA_DEL_GLOBAL_G_REF (cp_gtk_gdk_env(), jgraphics);
-}
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
deleted file mode 100644
index b42f649a1..000000000
--- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
+++ /dev/null
@@ -1,2018 +0,0 @@
-/* gnu_java_awt_peer_gtk_GdkGraphics2d.c
- Copyright (C) 2003, 2005, 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. */
-
-#include "jcl.h"
-#include "gtkcairopeer.h"
-#include "gdkfont.h"
-#include "gnu_java_awt_peer_gtk_GdkGraphics2D.h"
-#include <gdk/gdktypes.h>
-#include <gdk/gdkprivate.h>
-#include <gdk/gdkx.h>
-#include <X11/extensions/Xrender.h>
-
-#include <gdk-pixbuf/gdk-pixbuf.h>
-#include <gdk-pixbuf/gdk-pixdata.h>
-
-#include <cairo-ft.h>
-#include <cairo-xlib.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-
-static jmethodID initComponentGraphics2DUnlockedID;
-
-void
-cp_gtk_graphics2d_init_jni (void)
-{
- jclass gdkgraphics2d;
- JNIEnv *env = cp_gtk_gdk_env();
-
- gdkgraphics2d = (*env)->FindClass (env,
- "gnu/java/awt/peer/gtk/GdkGraphics2D");
- if ((*env)->ExceptionOccurred(env))
- return;
-
- initComponentGraphics2DUnlockedID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gdkgraphics2d,
- "initComponentGraphics2DUnlocked",
- "()V");
-}
-
-static struct state_table *native_graphics2d_state_table;
-
-#define NSA_G2D_INIT(env, clazz) \
- native_graphics2d_state_table = cp_gtk_init_state_table (env, clazz)
-
-#define NSA_GET_G2D_PTR(env, obj) \
- cp_gtk_get_state (env, obj, native_graphics2d_state_table)
-
-#define NSA_SET_G2D_PTR(env, obj, ptr) \
- cp_gtk_set_state (env, obj, native_graphics2d_state_table, (void *)ptr)
-
-#define NSA_DEL_G2D_PTR(env, obj) \
- cp_gtk_remove_state_slot (env, obj, native_graphics2d_state_table)
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initStaticState
- (JNIEnv *env, jclass clazz)
-{
- gdk_threads_enter();
-
- NSA_G2D_INIT (env, clazz);
-
- gdk_threads_leave();
-}
-
-/* these public final constants are part of the java2d public API, so we
- write them explicitly here to save fetching them from the constant pool
- all the time. */
-
-#ifndef min
-#define min(x,y) ((x) < (y) ? (x) : (y))
-#endif
-
-enum java_awt_alpha_composite_rule
- {
- java_awt_alpha_composite_CLEAR = 1,
- java_awt_alpha_composite_SRC = 2,
- java_awt_alpha_composite_SRC_OVER = 3,
- java_awt_alpha_composite_DST_OVER = 4,
- java_awt_alpha_composite_SRC_IN = 5,
- java_awt_alpha_composite_DST_IN = 6,
- java_awt_alpha_composite_SRC_OUT = 7,
- java_awt_alpha_composite_DST_OUT = 8,
- java_awt_alpha_composite_DST = 9,
- java_awt_alpha_composite_SRC_ATOP = 10,
- java_awt_alpha_composite_DST_ATOP = 11,
- java_awt_alpha_composite_XOR = 12
- };
-
-enum java_awt_basic_stroke_join_rule
- {
- java_awt_basic_stroke_JOIN_MITER = 0,
- java_awt_basic_stroke_JOIN_ROUND = 1,
- java_awt_basic_stroke_JOIN_BEVEL = 2
- };
-
-enum java_awt_basic_stroke_cap_rule
- {
- java_awt_basic_stroke_CAP_BUTT = 0,
- java_awt_basic_stroke_CAP_ROUND = 1,
- java_awt_basic_stroke_CAP_SQUARE = 2
- };
-
-enum java_awt_geom_path_iterator_winding_rule
- {
- java_awt_geom_path_iterator_WIND_EVEN_ODD = 0,
- java_awt_geom_path_iterator_WIND_NON_ZERO = 1
- };
-
-enum java_awt_rendering_hints_filter
- {
- java_awt_rendering_hints_VALUE_INTERPOLATION_NEAREST_NEIGHBOR = 0,
- java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR = 1,
- java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED = 2,
- java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY = 3,
- java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT = 4
-
- };
-
-static int
-peer_is_disposed(JNIEnv *env, jobject obj)
-{
- static jfieldID fid = NULL;
- jclass cls;
- jobject peer;
-
- return 0;
-
- if (fid == NULL)
- {
- cls = (*env)->GetObjectClass(env, obj);
- fid = (*env)->GetFieldID(env, cls, "component",
- "Lgnu/java/awt/peer/gtk/GtkComponentPeer;");
- }
- g_assert(fid != NULL);
- peer = (*env)->GetObjectField(env, obj, fid);
- if (peer == NULL || NSA_GET_PTR (env, peer) != NULL)
- return 0;
- else
- {
- return 1;
- }
-}
-
-
-static void
-grab_current_drawable (GtkWidget *widget, GdkDrawable **draw, GdkWindow **win)
-{
- g_assert (widget != NULL);
- g_assert (draw != NULL);
- g_assert (win != NULL);
-
- *win = widget->window;
-
- *draw = *win;
- gdk_window_get_internal_paint_info (*win, draw, 0, 0);
- g_object_ref (*draw);
-}
-
-
-static int
-x_server_has_render_extension (void)
-{
- int ev = 0, err = 0;
- return (int) XRenderQueryExtension (GDK_DISPLAY (), &ev, &err);
-}
-
-static void
-init_graphics2d_as_pixbuf (struct graphics2d *gr)
-{
- gint width, height;
- gint bits_per_sample = 8;
- gint total_channels = 4;
- gboolean has_alpha = TRUE;
-
- g_assert (gr != NULL);
- g_assert (gr->drawable != NULL);
-
- if (gr->debug) printf ("initializing graphics2d as pixbuf\n");
- gdk_drawable_get_size (gr->drawable, &width, &height);
- gr->drawbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
- has_alpha, bits_per_sample,
- width, height);
- g_assert (gr->drawbuf != NULL);
- g_assert (gdk_pixbuf_get_bits_per_sample (gr->drawbuf) == bits_per_sample);
- g_assert (gdk_pixbuf_get_n_channels (gr->drawbuf) == total_channels);
-
- gr->surface = cairo_image_surface_create_for_data (gdk_pixbuf_get_pixels (gr->drawbuf),
- CAIRO_FORMAT_ARGB32,
- gdk_pixbuf_get_width (gr->drawbuf),
- gdk_pixbuf_get_height (gr->drawbuf),
- gdk_pixbuf_get_rowstride (gr->drawbuf));
- g_assert (gr->surface != NULL);
- gr->mode = MODE_DRAWABLE_NO_RENDER;
- if (gr->cr != NULL)
- cairo_destroy (gr->cr);
- gr->cr = cairo_create (gr->surface);
-}
-
-static void
-init_graphics2d_as_renderable (struct graphics2d *gr)
-{
- Drawable draw;
- Display * dpy;
- Visual * vis;
-
- g_assert (gr != NULL);
- g_assert (gr->drawable != NULL);
-
- gr->drawbuf = NULL;
-
- if (gr->debug) printf ("initializing graphics2d as renderable\n");
- draw = gdk_x11_drawable_get_xid (gr->drawable);
-
- dpy = gdk_x11_drawable_get_xdisplay (gr->drawable);
- g_assert (dpy != NULL);
-
- vis = gdk_x11_visual_get_xvisual (gdk_drawable_get_visual (gr->drawable));
- g_assert (vis != NULL);
-
- gr->surface = cairo_xlib_surface_create (dpy, draw, vis, gr->width, gr->height);
- g_assert (gr->surface != NULL);
- gr->mode = MODE_DRAWABLE_WITH_RENDER;
- if (gr->cr != NULL)
- cairo_destroy (gr->cr);
- gr->cr = cairo_create (gr->surface);
-}
-
-static void
-begin_drawing_operation (JNIEnv *env, struct graphics2d * gr)
-{
- cairo_status_t cst = cairo_status (gr->cr);
- if (cst != CAIRO_STATUS_SUCCESS)
- {
- const char *detail = cairo_status_to_string (cst);
- JCL_ThrowException (env, "java/lang/InternalError", detail);
- (*env)->ExceptionDescribe (env);
- return;
- }
-
- switch (gr->mode)
- {
- case MODE_DRAWABLE_WITH_RENDER:
- break;
-
- case MODE_DRAWABLE_NO_RENDER:
- {
-
- gint drawable_width, drawable_height;
- gint pixbuf_width, pixbuf_height;
- gint width, height;
-
- gdk_drawable_get_size (gr->drawable, &drawable_width, &drawable_height);
- pixbuf_width = gdk_pixbuf_get_width (gr->drawbuf);
- pixbuf_height = gdk_pixbuf_get_height (gr->drawbuf);
- width = min (drawable_width, pixbuf_width);
- height = min (drawable_height, pixbuf_height);
-
- gdk_pixbuf_get_from_drawable (gr->drawbuf, /* destination pixbuf */
- gr->drawable,
- NULL, /* colormap */
- 0, 0, 0, 0,
- width, height);
-
- if (gr->debug) printf ("copied (%d, %d) pixels from GDK drawable to pixbuf\n",
- width, height);
- }
- break;
-
- case MODE_JAVA_ARRAY:
- {
- jboolean isCopy;
- gr->javabuf = (*env)->GetPrimitiveArrayCritical (env, gr->jarray, &isCopy);
- gr->isCopy |= isCopy;
- if (gr->isCopy)
- {
- /* Make sure that the pixel buffer copy is already initalized,
- i.e. we already failed to get direct access in initState. */
- g_assert (gr->javabuf_copy != NULL);
- memcpy (gr->javabuf_copy, gr->javabuf, gr->width * gr->height * 4);
- }
- }
- break;
- }
-}
-
-static void
-end_drawing_operation (JNIEnv *env, struct graphics2d * gr)
-{
- cairo_status_t cst = cairo_status (gr->cr);
- if (cst != CAIRO_STATUS_SUCCESS)
- {
- /* Report error. */
- const char *detail = cairo_status_to_string (cst);
- JCL_ThrowException (env, "java/lang/InternalError", detail);
- (*env)->ExceptionDescribe (env);
-
- /* Recreate cairo status. */
- cairo_destroy (gr->cr);
- gr->cr = cairo_create (gr->surface);
- return;
- }
-
- switch (gr->mode)
- {
- case MODE_DRAWABLE_WITH_RENDER:
- break;
-
- case MODE_DRAWABLE_NO_RENDER:
- {
-
- gint drawable_width, drawable_height;
- gint pixbuf_width, pixbuf_height;
- gint width, height;
-
- gdk_drawable_get_size (gr->drawable, &drawable_width, &drawable_height);
- pixbuf_width = gdk_pixbuf_get_width (gr->drawbuf);
- pixbuf_height = gdk_pixbuf_get_height (gr->drawbuf);
- width = min (drawable_width, pixbuf_width);
- height = min (drawable_height, pixbuf_height);
-
- gdk_draw_pixbuf (gr->drawable, NULL, gr->drawbuf,
- 0, 0, 0, 0,
- width, height,
- GDK_RGB_DITHER_NORMAL, 0, 0);
-
- if (gr->debug) printf ("copied (%d, %d) pixels from pixbuf to GDK drawable\n",
- width, height);
- }
- break;
-
- case MODE_JAVA_ARRAY:
- if (gr->isCopy)
- memcpy (gr->javabuf, gr->javabuf_copy, gr->width * gr->height * 4);
- (*env)->ReleasePrimitiveArrayCritical (env, gr->jarray, gr->javabuf, JNI_COMMIT);
- }
-}
-
-
-static void
-update_pattern_transform (struct graphics2d *gr)
-{
- cairo_matrix_t mat;
-
- g_assert (gr != NULL);
- if (gr->pattern == NULL)
- return;
-
- cairo_get_matrix (gr->cr, &mat);
- cairo_pattern_set_matrix (gr->pattern, &mat);
-}
-
-static void
-check_for_debug (struct graphics2d *gr)
-{
- gr->debug = (gboolean)(getenv("DEBUGJ2D") != NULL);
-}
-
-static void
-realize_cb (GtkWidget *widget __attribute__ ((unused)), jobject peer)
-{
- (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(),
- peer,
- initComponentGraphics2DUnlockedID);
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_copyState
- (JNIEnv *env, jobject obj, jobject old)
-{
- struct graphics2d *g = NULL, *g_old = NULL;
-
- gdk_threads_enter();
-
- g = (struct graphics2d *) g_malloc (sizeof (struct graphics2d));
- g_assert (g != NULL);
- memset (g, 0, sizeof(struct graphics2d));
-
- g_old = (struct graphics2d *) NSA_GET_G2D_PTR (env, old);
- g_assert (g_old != NULL);
-
- if (g_old->debug) printf ("copying state from existing graphics2d\n");
-
- g->debug = g_old->debug;
- g->mode = g_old->mode;
-
- g->width = g_old->width;
- g->height = g_old->height;
-
- if (g_old->mode == MODE_JAVA_ARRAY)
- {
- jint size = g->width * g->height * 4;
-
- g->jarray = (*env)->NewGlobalRef (env, g_old->jarray);
- g->javabuf = (*env)->GetIntArrayElements (env, g->jarray, &g->isCopy);
- g->isCopy = JNI_TRUE;
- g->javabuf_copy = (jint *) g_malloc (size);
- memcpy (g->javabuf_copy, g->javabuf, size);
- g->surface = cairo_image_surface_create_for_data ((unsigned char *) g->javabuf,
- CAIRO_FORMAT_ARGB32,
- g->width,
- g->height,
- g->width * 4);
- g_assert (g->surface != NULL);
- g->cr = cairo_create (g->surface);
- g_assert (g->cr != NULL);
- (*env)->ReleaseIntArrayElements (env, g->jarray, g->javabuf, JNI_ABORT);
- }
- else
- {
- g->drawable = g_old->drawable;
- g_object_ref (g->drawable);
-
- if (x_server_has_render_extension ())
- init_graphics2d_as_renderable (g);
- else
- init_graphics2d_as_pixbuf (g);
- }
-
- if (g->pattern)
- cairo_pattern_set_filter (g->pattern, CAIRO_FILTER_FAST);
-
- NSA_SET_G2D_PTR (env, obj, g);
-
- gdk_threads_leave();
-}
-
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState___3III
-(JNIEnv *env, jobject obj, jintArray jarr, jint width, jint height)
-{
- struct graphics2d *gr = NULL;
- jint *cairobuf = NULL;
-
- gdk_threads_enter();
-
- gr = (struct graphics2d *) g_malloc (sizeof (struct graphics2d));
- g_assert (gr != NULL);
- memset (gr, 0, sizeof(struct graphics2d));
-
- check_for_debug (gr);
-
- if (gr->debug) printf ("constructing java-backed image of size (%d,%d)\n",
- width, height);
-
- gr->width = width;
- gr->height = height;
- gr->jarray = (*env)->NewGlobalRef(env, jarr);
- gr->javabuf = (*env)->GetPrimitiveArrayCritical (env, gr->jarray, &gr->isCopy);
- if (gr->isCopy)
- {
- /* We didn't get direct access to the pixel buffer, so we'll have to
- maintain a separate copy for Cairo. */
- jint size = gr->width * gr->height * 4;
- gr->javabuf_copy = (jint *) g_malloc (size);
- memcpy (gr->javabuf_copy, gr->javabuf, size);
- cairobuf = gr->javabuf_copy;
- }
- else
- {
- /* Have Cairo write directly to the Java array. */
- cairobuf = gr->javabuf;
- }
- gr->surface = cairo_image_surface_create_for_data ((unsigned char *) cairobuf,
- CAIRO_FORMAT_ARGB32,
- gr->width,
- gr->height,
- gr->width * 4);
- g_assert (gr->surface != NULL);
- gr->cr = cairo_create (gr->surface);
- g_assert (gr->cr != NULL);
- (*env)->ReleasePrimitiveArrayCritical (env, gr->jarray, gr->javabuf, JNI_COMMIT);
-
- gr->mode = MODE_JAVA_ARRAY;
-
- if (gr->debug) printf ("constructed java-backed image of size (%d,%d)\n",
- width, height);
-
- NSA_SET_G2D_PTR (env, obj, gr);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState__II
- (JNIEnv *env, jobject obj, jint width, jint height)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- gr = (struct graphics2d *) g_malloc (sizeof (struct graphics2d));
- g_assert (gr != NULL);
- memset (gr, 0, sizeof(struct graphics2d));
-
- check_for_debug (gr);
-
- if (gr->debug) printf ("constructing offscreen drawable of size (%d,%d)\n",
- width, height);
-
- gr->drawable = (GdkDrawable *) gdk_pixmap_new (NULL, width, height,
- gdk_rgb_get_visual ()->depth);
- g_assert (gr->drawable != NULL);
-
- gr->width = width;
- gr->height = height;
-
- if (x_server_has_render_extension ())
- init_graphics2d_as_renderable (gr);
- else
- init_graphics2d_as_pixbuf (gr);
-
- if (gr->debug) printf ("constructed offscreen drawable of size (%d,%d)\n",
- width, height);
- NSA_SET_G2D_PTR (env, obj, gr);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_gdkDrawDrawable
- (JNIEnv *env, jobject self, jobject other, jint x, jint y)
-{
- struct graphics2d *src = NULL;
- struct graphics2d *dst = NULL;
- gint s_height;
- gint s_width;
- gint d_height;
- gint d_width;
- gint height;
- gint width;
- cairo_matrix_t matrix;
- cairo_operator_t tmp_op;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, self))
- {
- gdk_threads_leave();
- return;
- }
-
- src = (struct graphics2d *)NSA_GET_G2D_PTR (env, other);
- dst = (struct graphics2d *)NSA_GET_G2D_PTR (env, self);
- g_assert (src != NULL);
- g_assert (dst != NULL);
-
- if (src->debug) printf ("copying from offscreen drawable\n");
-
- begin_drawing_operation(env, dst);
-
- /* gdk_flush(); */
-
- if (!GDK_IS_DRAWABLE (src->drawable) ||
- !GDK_IS_DRAWABLE (dst->drawable))
- {
- gdk_threads_leave ();
- return;
- }
-
- gdk_drawable_get_size (src->drawable, &s_width, &s_height);
- gdk_drawable_get_size (dst->drawable, &d_width, &d_height);
- width = min (s_width, d_width);
- height = min (s_height, d_height);
-
- cairo_get_matrix (src->cr, &matrix);
- cairo_matrix_translate (&matrix, (double)-x, (double)-y);
- if (src->pattern)
- cairo_pattern_set_matrix (src->pattern, &matrix);
- tmp_op = cairo_get_operator (dst->cr);
- cairo_set_operator(dst->cr, CAIRO_OPERATOR_SOURCE);
- cairo_set_source_surface (dst->cr, src->surface, 0, 0);
- cairo_paint (dst->cr);
- cairo_set_operator(dst->cr, tmp_op);
-
- cairo_matrix_translate (&matrix, (double)x, (double)y);
- if (src->pattern)
- cairo_pattern_set_matrix (src->pattern, &matrix);
-
- gdk_flush();
-
- end_drawing_operation(env, dst);
-
- if (src->debug) printf ("copied %d x %d pixels from offscreen drawable\n", width, height);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initStateUnlocked
- (JNIEnv *env, jobject obj, jobject peer)
-{
- struct graphics2d *gr = NULL;
- GtkWidget *widget = NULL;
- void *ptr = NULL;
-
- if (peer_is_disposed(env, obj))
- return;
-
- ptr = NSA_GET_PTR (env, peer);
- g_assert (ptr != NULL);
-
- gr = (struct graphics2d *) g_malloc (sizeof (struct graphics2d));
- g_assert (gr != NULL);
- memset (gr, 0, sizeof(struct graphics2d));
-
- check_for_debug (gr);
-
- widget = GTK_WIDGET (ptr);
- g_assert (widget != NULL);
-
- grab_current_drawable (widget, &(gr->drawable), &(gr->win));
- g_assert (gr->drawable != NULL);
-
- gr->width = widget->allocation.width;
- gr->height = widget->allocation.height;
-
- if (x_server_has_render_extension ())
- init_graphics2d_as_renderable (gr);
- else
- init_graphics2d_as_pixbuf (gr);
-
- NSA_SET_G2D_PTR (env, obj, gr);
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState__Lgnu_java_awt_peer_gtk_GtkComponentPeer_2
- (JNIEnv *env, jobject obj, jobject peer)
-{
- struct graphics2d *gr = NULL;
- GtkWidget *widget = NULL;
- void *ptr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave ();
- return;
- }
-
- ptr = NSA_GET_PTR (env, peer);
- g_assert (ptr != NULL);
-
- gr = (struct graphics2d *) g_malloc (sizeof (struct graphics2d));
- g_assert (gr != NULL);
- memset (gr, 0, sizeof(struct graphics2d));
-
- check_for_debug (gr);
-
- widget = GTK_WIDGET (ptr);
- g_assert (widget != NULL);
-
- grab_current_drawable (widget, &(gr->drawable), &(gr->win));
- g_assert (gr->drawable != NULL);
-
- gr->width = widget->allocation.width;
- gr->height = widget->allocation.height;
-
- if (x_server_has_render_extension ())
- init_graphics2d_as_renderable (gr);
- else
- init_graphics2d_as_pixbuf (gr);
-
- NSA_SET_G2D_PTR (env, obj, gr);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_connectSignals
- (JNIEnv *env, jobject obj, jobject peer)
-{
- void *ptr;
-
- gdk_threads_enter ();
-
- ptr = NSA_GET_PTR (env, peer);
-
- g_signal_connect_after (G_OBJECT (ptr), "realize",
- G_CALLBACK (realize_cb), obj);
-
- gdk_threads_leave ();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_dispose
- (JNIEnv *env, jobject obj)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- gr = (struct graphics2d *) NSA_DEL_G2D_PTR (env, obj);
-
- if (gr == NULL)
- {
- gdk_threads_leave();
- return; /* dispose has been called more than once */
- }
-
- if (gr->surface)
- cairo_surface_destroy (gr->surface);
-
- cairo_destroy (gr->cr);
-
- if (gr->drawbuf)
- g_object_unref (gr->drawbuf);
-
- if (gr->drawable)
- g_object_unref (gr->drawable);
-
- if (gr->pattern)
- cairo_pattern_destroy (gr->pattern);
-
- if (gr->pattern_surface)
- cairo_surface_destroy (gr->pattern_surface);
-
- if (gr->pattern_pixels)
- g_free (gr->pattern_pixels);
-
- if (gr->mode == MODE_JAVA_ARRAY)
- {
- (*env)->DeleteGlobalRef (env, gr->jarray);
- if (gr->javabuf_copy)
- g_free (gr->javabuf_copy);
- }
-
- if (gr->debug) printf ("disposed of graphics2d\n");
-
- g_free (gr);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setGradient
- (JNIEnv *env, jobject obj,
- jdouble x1, jdouble y1,
- jdouble x2, jdouble y2,
- jint r1, jint g1, jint b1, jint a1,
- jint r2, jint g2, jint b2, jint a2,
- jboolean cyclic)
-{
- gdk_threads_enter();
- Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setGradientUnlocked
- (env, obj,
- x1, y1, x2, y2,
- r1, g1, b1, a1,
- r2, g2, b2, a2,
- cyclic);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setGradientUnlocked
- (JNIEnv *env, jobject obj,
- jdouble x1, jdouble y1,
- jdouble x2, jdouble y2,
- jint r1, jint g1, jint b1, jint a1,
- jint r2, jint g2, jint b2, jint a2,
- jboolean cyclic)
-{
- struct graphics2d *gr = NULL;
- cairo_surface_t *surf = NULL;
- cairo_t *cr2 = NULL;
- cairo_matrix_t mat;
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
-
- if (peer_is_disposed(env, obj))
- return;
-
- if (gr->debug)
- printf ("setGradientUnlocked (%f,%f) -> (%f,%f); (%d,%d,%d,%d) -> (%d,%d,%d,%d)\n",
- x1, y1,
- x2, y2,
- r1, g1, b1, a1,
- r2, g2, b2, a2);
-
- if (cyclic)
- surf = cairo_surface_create_similar (gr->surface, CAIRO_FORMAT_ARGB32, 3, 2);
- else
- surf = cairo_surface_create_similar (gr->surface, CAIRO_FORMAT_ARGB32, 2, 2);
- g_assert (surf != NULL);
-
- cr2 = cairo_create (surf);
-
- cairo_identity_matrix (cr2);
-
- cairo_set_source_rgba (cr2, r1 / 255.0, g1 / 255.0, b1 / 255.0, a1 / 255.0);
- cairo_rectangle (cr2, 0, 0, 1, 2);
- cairo_fill (cr2);
-
- cairo_set_source_rgba (cr2, r2 / 255.0, g2 / 255.0, b2 / 255.0, a2 / 255.0);
- cairo_rectangle (cr2, 1, 0, 1, 2);
- cairo_fill (cr2);
-
- if (cyclic)
- {
- cairo_set_source_rgba (cr2, r1 / 255.0, g1 / 255.0, b1 / 255.0, a1 / 255.0);
- cairo_rectangle (cr2, 2, 0, 1, 2);
- cairo_fill (cr2);
- }
-
- cairo_matrix_init_identity (&mat);
-
- /*
- consider the vector [x2 - x1, y2 - y1] = [p,q]
-
- this is a line in space starting at an 'origin' x1, y1.
-
- it can also be thought of as a "transformed" unit vector in either the
- x or y directions. we have just *drawn* our gradient as a unit vector
- (well, a 2-3x unit vector) in the x dimension. so what we want to know
- is which transformation turns our existing unit vector into [p,q].
-
- which means solving for M in
-
- [p,q] = M[1,0]
-
- [p,q] = |a b| [1,0]
- |c d|
-
- [p,q] = [a,c], with b = d = 0.
-
- what does this mean? it means that our gradient is 1-dimensional; as
- you move through the x axis of our 2 or 3 pixel gradient from logical
- x positions 0 to 1, the transformation of your x coordinate under the
- matrix M causes you to accumulate both x and y values in fill
- space. the y value of a gradient coordinate is ignored, since the
- gradient is one dimensional. which is correct.
-
- unfortunately we want the opposite transformation, it seems, because of
- the way cairo is going to use this transformation. I'm a bit confused by
- that, but it seems to work right, so we take reciprocals of values and
- negate offsets. oh well.
-
- */
- {
- double a = (x2 - x1 == 0.) ? 0. : ((cyclic ? 3.0 : 2.0) / (x2 - x1));
- double c = (y2 - y1 == 0.) ? 0. : (1. / (y2 - y1));
- double dx = (x1 == 0.) ? 0. : 1. / x1;
- double dy = (y1 == 0.) ? 0. : 1. / y1;
- cairo_pattern_t *p;
-
- cairo_matrix_init (&mat,
- a, 0.,
- c, 0.,
- dx, dy);
-
- p = cairo_pattern_create_for_surface (surf);
- cairo_pattern_set_matrix (p, &mat);
- cairo_pattern_set_filter (p, CAIRO_FILTER_BILINEAR);
- }
-
- /* FIXME: repeating gradients (not to mention hold gradients) don't seem to work. */
- /* cairo_surface_set_repeat (surf, cyclic ? 1 : 0); */
-
- if (gr->pattern)
- cairo_pattern_destroy (gr->pattern);
-
- if (gr->pattern_surface)
- cairo_surface_destroy (gr->pattern_surface);
-
- if (gr->pattern_pixels)
- g_free (gr->pattern_pixels);
-
- gr->pattern_pixels = NULL;
- gr->pattern_surface = surf;
- gr->pattern = cairo_pattern_create_for_surface(surf);
-
- cairo_set_source (gr->cr, gr->pattern);
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setTexturePixels
- (JNIEnv *env, jobject obj, jintArray jarr, jint w, jint h, jint stride)
-{
- gdk_threads_enter();
-
- Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setTexturePixelsUnlocked
- (env, obj, jarr, w, h, stride);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setTexturePixelsUnlocked
- (JNIEnv *env, jobject obj, jintArray jarr, jint w, jint h, jint stride)
-{
- struct graphics2d *gr = NULL;
- jint *jpixels = NULL;
-
- if (peer_is_disposed(env, obj))
- return;
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
-
- if (gr->debug)
- printf ("setTexturePixelsUnlocked (%d pixels, %dx%d, stride: %d)\n",
- (*env)->GetArrayLength (env, jarr), w, h, stride);
-
- if (gr->pattern)
- cairo_pattern_destroy (gr->pattern);
-
- if (gr->pattern_surface)
- cairo_surface_destroy (gr->pattern_surface);
-
- if (gr->pattern_pixels)
- g_free (gr->pattern_pixels);
-
- gr->pattern = NULL;
- gr->pattern_surface = NULL;
- gr->pattern_pixels = NULL;
-
- gr->pattern_pixels = (char *) g_malloc (h * stride * 4);
- g_assert (gr->pattern_pixels != NULL);
-
- jpixels = (*env)->GetIntArrayElements (env, jarr, NULL);
- g_assert (jpixels != NULL);
- memcpy (gr->pattern_pixels, jpixels, h * stride * 4);
- (*env)->ReleaseIntArrayElements (env, jarr, jpixels, 0);
-
- gr->pattern_surface = cairo_image_surface_create_for_data ((unsigned char *)gr->pattern_pixels,
- CAIRO_FORMAT_ARGB32,
- w, h, stride * 4);
- g_assert (gr->pattern_surface != NULL);
- gr->pattern = cairo_pattern_create_for_surface (gr->pattern_surface);
- g_assert (gr->pattern != NULL);
- cairo_pattern_set_extend (gr->pattern, CAIRO_EXTEND_REPEAT);
- cairo_set_source (gr->cr, gr->pattern);
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_drawPixels
- (JNIEnv *env, jobject obj, jintArray java_pixels,
- jint w, jint h, jint stride, jdoubleArray java_matrix)
-{
- struct graphics2d *gr = NULL;
- jint *native_pixels = NULL;
- jdouble *native_matrix = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
-
- if (gr->debug)
- printf ("drawPixels (%d pixels, %dx%d, stride: %d)\n",
- (*env)->GetArrayLength (env, java_pixels), w, h, stride);
-
- native_pixels = (*env)->GetIntArrayElements (env, java_pixels, NULL);
- native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL);
- g_assert (native_pixels != NULL);
- g_assert (native_matrix != NULL);
- g_assert ((*env)->GetArrayLength (env, java_matrix) == 6);
-
- begin_drawing_operation (env, gr);
-
- {
- cairo_matrix_t mat;
- cairo_pattern_t *p;
- cairo_surface_t *surf = cairo_image_surface_create_for_data ((unsigned char *)native_pixels,
- CAIRO_FORMAT_ARGB32,
- w, h, stride * 4);
- cairo_matrix_init_identity (&mat);
- cairo_matrix_init (&mat,
- native_matrix[0], native_matrix[1],
- native_matrix[2], native_matrix[3],
- native_matrix[4], native_matrix[5]);
-
- p = cairo_pattern_create_for_surface (surf);
- cairo_pattern_set_matrix (p, &mat);
- if (gr->pattern)
- cairo_pattern_set_filter (p, cairo_pattern_get_filter (gr->pattern));
- cairo_set_source (gr->cr, p);
- cairo_paint (gr->cr);
- cairo_pattern_destroy (p);
- cairo_surface_destroy (surf);
- }
-
- end_drawing_operation (env, gr);
-
- (*env)->ReleaseIntArrayElements (env, java_pixels, native_pixels, 0);
- (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0);
-
- gdk_threads_leave();
-}
-
-/* passthrough methods to cairo */
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSave
- (JNIEnv *env, jobject obj)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_save\n");
- cairo_save (gr->cr);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRestore
- (JNIEnv *env, jobject obj)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_restore\n");
- cairo_restore (gr->cr);
- update_pattern_transform (gr);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMatrix
- (JNIEnv *env, jobject obj, jdoubleArray java_matrix)
-{
- gdk_threads_enter();
-
- Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMatrixUnlocked
- (env, obj, java_matrix);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMatrixUnlocked
- (JNIEnv *env, jobject obj, jdoubleArray java_matrix)
-{
- struct graphics2d *gr = NULL;
- jdouble *native_matrix = NULL;
-
- if (peer_is_disposed(env, obj))
- return;
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
-
- /* cairoSetMatrix was called before this graphics object's component
- was realized. */
- if (gr == NULL)
- return;
-
- native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL);
- g_assert (native_matrix != NULL);
- g_assert ((*env)->GetArrayLength (env, java_matrix) == 6);
-
- if (gr->debug)
- printf ("cairo_matrix_init [ %f, %f, %f, %f, %f, %f ]\n",
- native_matrix[0], native_matrix[1],
- native_matrix[2], native_matrix[3],
- native_matrix[4], native_matrix[5]);
-
- {
- cairo_matrix_t mat;
-
- cairo_matrix_init_identity (&mat);
- cairo_matrix_init (&mat,
- native_matrix[0], native_matrix[1],
- native_matrix[2], native_matrix[3],
- native_matrix[4], native_matrix[5]);
- cairo_set_matrix (gr->cr, &mat);
- }
-
- (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0);
- update_pattern_transform (gr);
-}
-
-static void
-install_font_peer(cairo_t *cr,
- struct peerfont *pfont,
- int debug)
-{
- cairo_font_face_t *ft;
- FT_Face face = NULL;
-
- g_assert(cr != NULL);
- g_assert(pfont != NULL);
-
- if (pfont->graphics_resource == NULL)
- {
- face = pango_ft2_font_get_face (pfont->font);
- g_assert (face != NULL);
-
- ft = cairo_ft_font_face_create_for_ft_face (face, 0);
- g_assert (ft != NULL);
-
- if (debug) printf ("install_font_peer made new cairo font for '%s' at %f\n",
- face->family_name,
- (pango_font_description_get_size (pfont->desc) /
- (double)PANGO_SCALE));
-
- cairo_set_font_face (cr, ft);
- cairo_font_face_destroy (ft);
- cairo_set_font_size (cr,
- (pango_font_description_get_size (pfont->desc) /
- (double)PANGO_SCALE));
- ft = cairo_get_font_face (cr);
- pfont->graphics_resource = ft;
- }
- else
- {
- if (debug) printf ("install_font_peer reused existing font resource\n");
- ft = (cairo_font_face_t *) pfont->graphics_resource;
- cairo_set_font_face (cr, ft);
- }
-}
-
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_releasePeerGraphicsResource
- (JNIEnv *env, jclass clazz __attribute__ ((unused)), jobject java_font)
-{
- struct peerfont *pfont = NULL;
-
- gdk_threads_enter();
-
- g_assert(java_font != NULL);
-
- pfont = (struct peerfont *) NSA_GET_FONT_PTR (env, java_font);
- g_assert (pfont != NULL);
- if (pfont->graphics_resource != NULL)
- {
- cairo_font_face_destroy ((cairo_font_face_t *) pfont->graphics_resource);
- pfont->graphics_resource = NULL;
- }
-
- gdk_threads_leave();
-}
-
-static void
-paint_glyph_run(JNIEnv *env,
- struct graphics2d *gr,
- cairo_glyph_t **glyphs,
- gint *n_glyphs,
- PangoLayoutRun *run)
-{
- gint i = 0;
- gint x = 0, y = 0;
-
- g_assert (gr != NULL);
- g_assert (glyphs != NULL);
- g_assert (n_glyphs != NULL);
- g_assert (run != NULL);
-
- if (run->glyphs != NULL && run->glyphs->num_glyphs > 0)
- {
- if (*n_glyphs < run->glyphs->num_glyphs)
- {
- *glyphs = g_realloc(*glyphs,
- (sizeof(cairo_glyph_t)
- * run->glyphs->num_glyphs));
- *n_glyphs = run->glyphs->num_glyphs;
- }
-
- g_assert (*glyphs != NULL);
-
- if (gr->debug) printf ("painting %d glyphs: ", run->glyphs->num_glyphs);
-
- for (i = 0; i < run->glyphs->num_glyphs; ++i)
- {
- (*glyphs)[i].index = run->glyphs->glyphs[i].glyph;
-
- (*glyphs)[i].x =
- ((double) (x + run->glyphs->glyphs[i].geometry.x_offset))
- / ((double) PANGO_SCALE);
-
- (*glyphs)[i].y =
- ((double) (y + run->glyphs->glyphs[i].geometry.y_offset))
- / ((double) PANGO_SCALE);
-
- if (gr->debug) printf(" (%ld @ %f,%f)",
- (*glyphs)[i].index,
- (*glyphs)[i].x,
- (*glyphs)[i].y);
-
- x += run->glyphs->glyphs[i].geometry.width;
- }
-
- if (gr->debug) printf("\n");
- begin_drawing_operation (env, gr);
- cairo_show_glyphs (gr->cr, *glyphs, run->glyphs->num_glyphs);
- end_drawing_operation (env, gr);
- }
-}
-
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoDrawGlyphVector
- (JNIEnv *env, jobject self,
- jobject font,
- jfloat x, jfloat y, jint n,
- jintArray java_codes,
- jfloatArray java_positions)
-{
-
- struct graphics2d *gr = NULL;
- struct peerfont *pfont = NULL;
- cairo_glyph_t *glyphs = NULL;
- int *native_codes;
- float *native_positions;
- jint i = 0;
-
- gdk_threads_enter ();
-
- g_assert (self != NULL);
- g_assert (java_codes != NULL);
- g_assert (java_positions != NULL);
-
- if (peer_is_disposed(env, self))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *)NSA_GET_G2D_PTR (env, self);
- g_assert (gr != NULL);
-
- pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, font);
- g_assert (pfont != NULL);
-
- install_font_peer(gr->cr, pfont, gr->debug);
-
- glyphs = g_malloc( sizeof(cairo_glyph_t) * n);
- g_assert (glyphs != NULL);
-
- native_codes = (*env)->GetIntArrayElements (env, java_codes, NULL);
- native_positions = (*env)->GetFloatArrayElements (env, java_positions, NULL);
-
- for (i = 0; i < n; ++i)
- {
- glyphs[i].index = native_codes[i];
- glyphs[i].x = x + native_positions[ 2*i ];
- glyphs[i].y = y + native_positions[ 2*i + 1];
- }
-
- (*env)->ReleaseFloatArrayElements (env, java_positions, native_positions, 0);
- (*env)->ReleaseIntArrayElements (env, java_codes, native_codes, 0);
-
- begin_drawing_operation (env, gr);
- cairo_show_glyphs (gr->cr, glyphs, n);
- end_drawing_operation (env, gr);
-
- g_free(glyphs);
-
- gdk_threads_leave ();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoDrawGdkTextLayout
- (JNIEnv *env, jobject self, jobject java_layout, jfloat x, jfloat y)
-{
- /*
- * FIXME: Some day we expect either cairo or pango will know how to make
- * a pango layout paint to a cairo surface. that day is not yet here.
- */
-
- struct graphics2d *gr = NULL;
- struct textlayout *tl = NULL;
- PangoLayoutIter *i = NULL;
- PangoLayoutRun *run = NULL;
- cairo_glyph_t *glyphs = NULL;
- gint n_glyphs = 0;
-
- gdk_threads_enter ();
-
- g_assert (self != NULL);
- g_assert (java_layout != NULL);
-
- gr = (struct graphics2d *)NSA_GET_G2D_PTR (env, self);
- tl = (struct textlayout *)NSA_GET_TEXT_LAYOUT_PTR (env, java_layout);
-
- g_assert (gr != NULL);
- g_assert (tl != NULL);
- g_assert (tl->pango_layout != NULL);
-
- if (gr->debug) printf ("painting pango layout\n");
-
- if (peer_is_disposed(env, self))
- {
- gdk_threads_leave();
- return;
- }
-
- i = pango_layout_get_iter (tl->pango_layout);
- g_assert (i != NULL);
-
- cairo_translate (gr->cr, x, y);
-
- do
- {
- run = pango_layout_iter_get_run (i);
- if (run != NULL)
- paint_glyph_run (env, gr, &glyphs, &n_glyphs, run);
- }
- while (pango_layout_iter_next_run (i));
-
- if (glyphs != NULL)
- g_free (glyphs);
-
- cairo_translate (gr->cr, -x, -y);
-
- pango_layout_iter_free (i);
-
- gdk_threads_leave ();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetOperator
- (JNIEnv *env, jobject obj, jint op)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_set_operator %d\n", op);
- switch ((enum java_awt_alpha_composite_rule) op)
- {
- case java_awt_alpha_composite_CLEAR:
- cairo_set_operator (gr->cr, CAIRO_OPERATOR_CLEAR);
- break;
-
- case java_awt_alpha_composite_SRC:
- cairo_set_operator (gr->cr, CAIRO_OPERATOR_SOURCE);
- break;
-
- case java_awt_alpha_composite_SRC_OVER:
- cairo_set_operator (gr->cr, CAIRO_OPERATOR_OVER);
- break;
-
- case java_awt_alpha_composite_DST_OVER:
- cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_OVER);
- break;
-
- case java_awt_alpha_composite_SRC_IN:
- cairo_set_operator (gr->cr, CAIRO_OPERATOR_IN);
- break;
-
- case java_awt_alpha_composite_DST_IN:
- cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_IN);
- break;
-
- case java_awt_alpha_composite_SRC_OUT:
- cairo_set_operator (gr->cr, CAIRO_OPERATOR_OUT);
- break;
-
- case java_awt_alpha_composite_DST_OUT:
- cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_OUT);
- break;
-
- case java_awt_alpha_composite_DST:
- cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST);
- break;
-
- case java_awt_alpha_composite_SRC_ATOP:
- cairo_set_operator (gr->cr, CAIRO_OPERATOR_ATOP);
- break;
-
- case java_awt_alpha_composite_DST_ATOP:
- cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_ATOP);
- break;
-
- case java_awt_alpha_composite_XOR:
- cairo_set_operator (gr->cr, CAIRO_OPERATOR_XOR);
- break;
- }
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetRGBAColor
- (JNIEnv *env, jobject obj, jdouble r, jdouble g, jdouble b, jdouble a)
-{
- gdk_threads_enter();
-
- Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetRGBAColorUnlocked
- (env, obj, r, g, b, a);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetRGBAColorUnlocked
- (JNIEnv *env, jobject obj, jdouble r, jdouble g, jdouble b, jdouble a)
-{
- struct graphics2d *gr = NULL;
-
- if (peer_is_disposed(env, obj))
- return;
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
-
- /* this is a very weird fact: GDK Pixbufs and RENDER drawables consider
- colors in opposite pixel order. I have no idea why. thus when you
- draw to a PixBuf, you must exchange the R and B components of your
- color. */
-
- if (gr->debug)
- printf ("cairo_set_source_rgba (%f, %f, %f, %f)\n", r, g, b, a);
-
- if (gr->drawbuf)
- cairo_set_source_rgba (gr->cr, b, g, r, a);
- else
- cairo_set_source_rgba (gr->cr, r, g, b, a);
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetFillRule
- (JNIEnv *env, jobject obj, jint rule)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- if (gr->debug) printf ("cairo_set_fill_rule %d\n", rule);
- g_assert (gr != NULL);
- switch ((enum java_awt_geom_path_iterator_winding_rule) rule)
- {
- case java_awt_geom_path_iterator_WIND_NON_ZERO:
- cairo_set_fill_rule (gr->cr, CAIRO_FILL_RULE_WINDING);
- break;
- case java_awt_geom_path_iterator_WIND_EVEN_ODD:
- cairo_set_fill_rule (gr->cr, CAIRO_FILL_RULE_EVEN_ODD);
- break;
- }
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineWidth
- (JNIEnv *env, jobject obj, jdouble width)
-{
- gdk_threads_enter();
-
- Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineWidthUnlocked
- (env, obj, width);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineWidthUnlocked
- (JNIEnv *env, jobject obj, jdouble width)
-{
- struct graphics2d *gr = NULL;
-
- if (peer_is_disposed(env, obj))
- return;
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_set_line_width %f\n", width);
- cairo_set_line_width (gr->cr, width);
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineCap
- (JNIEnv *env, jobject obj, jint cap)
-{
- gdk_threads_enter();
-
- Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineCapUnlocked
- (env, obj, cap);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineCapUnlocked
- (JNIEnv *env, jobject obj, jint cap)
-{
- struct graphics2d *gr = NULL;
-
- if (peer_is_disposed(env, obj))
- return;
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_set_line_cap %d\n", cap);
- switch ((enum java_awt_basic_stroke_cap_rule) cap)
- {
- case java_awt_basic_stroke_CAP_BUTT:
- cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_BUTT);
- break;
-
- case java_awt_basic_stroke_CAP_ROUND:
- cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_ROUND);
- break;
-
- case java_awt_basic_stroke_CAP_SQUARE:
- cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_SQUARE);
- break;
- }
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineJoin
- (JNIEnv *env, jobject obj, jint join)
-{
- gdk_threads_enter();
-
- Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineJoinUnlocked
- (env, obj, join);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineJoinUnlocked
- (JNIEnv *env, jobject obj, jint join)
-{
- struct graphics2d *gr = NULL;
-
- if (peer_is_disposed(env, obj))
- return;
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_set_line_join %d\n", join);
- switch ((enum java_awt_basic_stroke_join_rule) join)
- {
- case java_awt_basic_stroke_JOIN_MITER:
- cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_MITER);
- break;
-
- case java_awt_basic_stroke_JOIN_ROUND:
- cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_ROUND);
- break;
-
- case java_awt_basic_stroke_JOIN_BEVEL:
- cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_BEVEL);
- break;
- }
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetDash
- (JNIEnv *env, jobject obj, jdoubleArray dashes, jint ndash, jdouble offset)
-{
- gdk_threads_enter();
-
- Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetDashUnlocked
- (env, obj, dashes, ndash, offset);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetDashUnlocked
- (JNIEnv *env, jobject obj, jdoubleArray dashes, jint ndash, jdouble offset)
-{
- struct graphics2d *gr = NULL;
- jdouble *dasharr = NULL;
-
- if (peer_is_disposed(env, obj))
- return;
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_set_dash\n");
- dasharr = (*env)->GetDoubleArrayElements (env, dashes, NULL);
- g_assert (dasharr != NULL);
- cairo_set_dash (gr->cr, dasharr, ndash, offset);
- (*env)->ReleaseDoubleArrayElements (env, dashes, dasharr, 0);
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMiterLimit
- (JNIEnv *env, jobject obj, jdouble miter)
-{
- gdk_threads_enter();
-
- Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMiterLimitUnlocked
- (env, obj, miter);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMiterLimitUnlocked
- (JNIEnv *env, jobject obj, jdouble miter)
-{
- struct graphics2d *gr = NULL;
-
- if (peer_is_disposed(env, obj))
- return;
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_set_miter_limit %f\n", miter);
- cairo_set_miter_limit (gr->cr, miter);
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoNewPath
- (JNIEnv *env, jobject obj)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
-
- if (gr == NULL)
- {
- gdk_threads_leave ();
- return;
- }
-
- if (gr->debug) printf ("cairo_new_path\n");
- cairo_new_path (gr->cr);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoMoveTo
- (JNIEnv *env, jobject obj, jdouble x, jdouble y)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_move_to (%f, %f)\n", x, y);
- cairo_move_to (gr->cr, x, y);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoLineTo
- (JNIEnv *env, jobject obj, jdouble x, jdouble y)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_line_to (%f, %f)\n", x, y);
- cairo_line_to (gr->cr, x, y);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoCurveTo
- (JNIEnv *env, jobject obj, jdouble x1, jdouble y1, jdouble x2, jdouble y2, jdouble x3, jdouble y3)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug)
- printf ("cairo_curve_to (%f, %f), (%f, %f), (%f, %f)\n",
- x1, y1, x2, y2, x3, y3);
- cairo_curve_to (gr->cr, x1, y1, x2, y2, x3, y3);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelMoveTo
- (JNIEnv *env, jobject obj, jdouble dx, jdouble dy)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_rel_move_to (%f, %f)\n", dx, dy);
- cairo_rel_move_to (gr->cr, dx, dy);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelLineTo
- (JNIEnv *env, jobject obj, jdouble dx, jdouble dy)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_rel_line_to (%f, %f)\n", dx, dy);
- cairo_rel_line_to (gr->cr, dx, dy);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelCurveTo
- (JNIEnv *env, jobject obj, jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2, jdouble dx3, jdouble dy3)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug)
- printf ("cairo_rel_curve_to (%f, %f), (%f, %f), (%f, %f)\n",
- dx1, dy1, dx2, dy2, dx3, dy3);
- cairo_rel_curve_to (gr->cr, dx1, dy1, dx2, dy2, dx3, dy3);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRectangle
- (JNIEnv *env, jobject obj, jdouble x, jdouble y, jdouble width, jdouble height)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
-
- if (gr == NULL)
- {
- gdk_threads_leave ();
- return;
- }
-
- if (gr->debug)
- printf ("cairo_rectangle (%f, %f) (%f, %f)\n", x, y, width, height);
- cairo_rectangle (gr->cr, x, y, width, height);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoClosePath
- (JNIEnv *env, jobject obj)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_close_path\n");
- cairo_close_path (gr->cr);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoStroke
- (JNIEnv *env, jobject obj)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_stroke\n");
- begin_drawing_operation (env, gr);
- cairo_stroke (gr->cr);
- end_drawing_operation (env, gr);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoFill
- (JNIEnv *env, jobject obj)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_fill\n");
- begin_drawing_operation (env, gr);
- cairo_fill (gr->cr);
- end_drawing_operation (env, gr);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoClip
- (JNIEnv *env, jobject obj)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
-
- if (gr == NULL)
- {
- gdk_threads_leave ();
- return;
- }
-
- if (gr->debug) printf ("cairo_clip\n");
- begin_drawing_operation (env, gr);
- cairo_reset_clip (gr->cr);
- cairo_clip (gr->cr);
- end_drawing_operation (env, gr);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSurfaceSetFilter
- (JNIEnv *env, jobject obj, jint filter)
-{
- gdk_threads_enter();
-
- Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSurfaceSetFilterUnlocked
- (env, obj, filter);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSurfaceSetFilterUnlocked
- (JNIEnv *env, jobject obj, jint filter)
-{
- struct graphics2d *gr = NULL;
-
- if (peer_is_disposed(env, obj))
- return;
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
-
- if (gr->pattern == NULL)
- return;
-
- if (gr->debug) printf ("cairo_pattern_set_filter %d\n", filter);
- switch ((enum java_awt_rendering_hints_filter) filter)
- {
- case java_awt_rendering_hints_VALUE_INTERPOLATION_NEAREST_NEIGHBOR:
- cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_NEAREST);
- break;
- case java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR:
- cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_BILINEAR);
- break;
- case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED:
- cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_FAST);
- break;
- case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT:
- cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_NEAREST);
- break;
- case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY:
- cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_BEST);
- break;
- }
-}
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c
index edce3917d..92f2d37ca 100644
--- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c
@@ -1,5 +1,5 @@
/* gnu_java_awt_GdkTextLayout.c
- Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -47,6 +47,7 @@
#include "native_state.h"
#include "gdkfont.h"
#include "gnu_java_awt_peer_gtk_GdkTextLayout.h"
+#include "cairographics2d.h"
struct state_table *cp_gtk_native_text_layout_state_table;
@@ -60,6 +61,9 @@ typedef struct gp
double sy;
} generalpath ;
+static void paint_glyph_run(cairo_t *cr, cairo_glyph_t **glyphs,
+ gint *n_glyphs, PangoLayoutRun *run);
+
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkTextLayout_initStaticState
(JNIEnv *env, jclass clazz)
@@ -93,8 +97,6 @@ Java_gnu_java_awt_peer_gtk_GdkTextLayout_setText
gchar *str = NULL;
gint len = 0;
- gdk_threads_enter ();
-
g_assert(self != NULL);
g_assert(text != NULL);
@@ -106,13 +108,37 @@ Java_gnu_java_awt_peer_gtk_GdkTextLayout_setText
str = (gchar *)(*env)->GetStringUTFChars (env, text, NULL);
g_assert (str != NULL);
- pango_layout_set_text (tl->pango_layout, text, len);
+ gdk_threads_enter ();
+
+ pango_layout_set_text (tl->pango_layout, str, len);
(*env)->ReleaseStringUTFChars (env, text, str);
gdk_threads_leave ();
}
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkTextLayout_setFont (JNIEnv *env, jobject obj, jobject font)
+{
+ struct textlayout *tl;
+ struct peerfont *pf;
+
+ g_assert(obj != NULL);
+ g_assert(font != NULL);
+
+ tl = (struct textlayout *)NSA_GET_TEXT_LAYOUT_PTR (env, obj);
+ g_assert(tl != NULL);
+ g_assert(tl->pango_layout != NULL);
+ pf = (struct peerfont *)NSA_GET_FONT_PTR (env, font);
+ g_assert(pf != NULL);
+
+ gdk_threads_enter ();
+
+ pango_layout_set_font_description(tl->pango_layout, pf->desc);
+
+ gdk_threads_leave ();
+}
+
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkTextLayout_indexToPos
(JNIEnv *env, jobject self, jint idx, jdoubleArray javaPos)
@@ -207,10 +233,108 @@ Java_gnu_java_awt_peer_gtk_GdkTextLayout_dispose
gdk_threads_leave ();
}
+/**
+ * Draw this textlayout on a cairo surface
+ * FIXME: Seems completely broken.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkTextLayout_cairoDrawGdkTextLayout
+ (JNIEnv *env, jobject obj, jobject cairographics, jfloat x, jfloat y)
+{
+ /*
+ * FIXME: Some day we expect either cairo or pango will know how to make
+ * a pango layout paint to a cairo surface. that day is not yet here.
+ */
+
+ cairo_t *cr;
+ struct textlayout *tl = NULL;
+ PangoLayoutIter *i = NULL;
+ PangoLayoutRun *run = NULL;
+ cairo_glyph_t *glyphs = NULL;
+ gint n_glyphs = 0;
+
+ g_assert (cairographics != NULL);
+
+ cr = cp_gtk_get_cairo_t(env, cairographics);
+ tl = (struct textlayout *)NSA_GET_TEXT_LAYOUT_PTR (env, obj);
+
+ g_assert (cr != NULL);
+ g_assert (tl != NULL);
+ g_assert (tl->pango_layout != NULL);
+
+ gdk_threads_enter ();
+
+ i = pango_layout_get_iter (tl->pango_layout);
+ g_assert (i != NULL);
+
+ cairo_translate (cr, x, y);
+
+ do
+ {
+ run = pango_layout_iter_get_run (i);
+ if (run != NULL)
+ paint_glyph_run (cr, &glyphs, &n_glyphs, run);
+ }
+ while (pango_layout_iter_next_run (i));
+
+ if (glyphs != NULL)
+ g_free (glyphs);
+
+ cairo_translate (cr, -x, -y);
+
+ pango_layout_iter_free (i);
+
+ gdk_threads_leave ();
+}
+
+static void
+paint_glyph_run(cairo_t *cr,
+ cairo_glyph_t **glyphs,
+ gint *n_glyphs,
+ PangoLayoutRun *run)
+{
+ gint i = 0;
+ gint x = 0, y = 0;
+
+ g_assert (cr != NULL);
+ g_assert (glyphs != NULL);
+ g_assert (n_glyphs != NULL);
+ g_assert (run != NULL);
+
+ if (run->glyphs != NULL && run->glyphs->num_glyphs > 0)
+ {
+ if (*n_glyphs < run->glyphs->num_glyphs)
+ {
+ *glyphs = g_realloc(*glyphs,
+ (sizeof(cairo_glyph_t)
+ * run->glyphs->num_glyphs));
+ *n_glyphs = run->glyphs->num_glyphs;
+ }
+
+ g_assert (*glyphs != NULL);
+
+ for (i = 0; i < run->glyphs->num_glyphs; ++i)
+ {
+ (*glyphs)[i].index = run->glyphs->glyphs[i].glyph;
+
+ (*glyphs)[i].x =
+ ((double) (x + run->glyphs->glyphs[i].geometry.x_offset))
+ / ((double) PANGO_SCALE);
+
+ (*glyphs)[i].y =
+ ((double) (y + run->glyphs->glyphs[i].geometry.y_offset))
+ / ((double) PANGO_SCALE);
+
+ x += run->glyphs->glyphs[i].geometry.width;
+ }
+ cairo_show_glyphs (cr, *glyphs, run->glyphs->num_glyphs);
+ }
+}
+
/* GetOutline code follows ****************************/
/********* Freetype callback functions *****************************/
-static int _moveTo( FT_Vector* to,
+static int _moveTo( const FT_Vector* to,
void *p)
{
JNIEnv *env;
@@ -233,7 +357,7 @@ static int _moveTo( FT_Vector* to,
return 0;
}
-static int _lineTo( FT_Vector* to,
+static int _lineTo( const FT_Vector* to,
void *p)
{
JNIEnv *env;
@@ -255,8 +379,8 @@ static int _lineTo( FT_Vector* to,
return 0;
}
-static int _quadTo( FT_Vector* cp,
- FT_Vector* to,
+static int _quadTo( const FT_Vector* cp,
+ const FT_Vector* to,
void *p)
{
JNIEnv *env;
@@ -280,9 +404,9 @@ static int _quadTo( FT_Vector* cp,
return 0;
}
-static int _curveTo( FT_Vector* cp1,
- FT_Vector* cp2,
- FT_Vector* to,
+static int _curveTo( const FT_Vector* cp1,
+ const FT_Vector* cp2,
+ const FT_Vector* to,
void *p)
{
JNIEnv *env;
@@ -320,10 +444,10 @@ Java_gnu_java_awt_peer_gtk_GdkTextLayout_getOutline
PangoLayoutLine *current_line;
FT_Outline_Funcs ftCallbacks =
{
- _moveTo,
- _lineTo,
- _quadTo,
- _curveTo,
+ (FT_Outline_MoveToFunc) _moveTo,
+ (FT_Outline_LineToFunc) _lineTo,
+ (FT_Outline_ConicToFunc) _quadTo,
+ (FT_Outline_CubicToFunc) _curveTo,
0,
0
};
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.c
index f44361972..ef9ac1207 100644
--- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.c
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.c
@@ -56,17 +56,3 @@ Java_gnu_java_awt_peer_gtk_GtkCanvasPeer_create
gdk_threads_leave ();
}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GtkCanvasPeer_realize (JNIEnv *env, jobject obj)
-{
- void *ptr;
-
- gdk_threads_enter ();
-
- ptr = NSA_GET_PTR (env, obj);
-
- gtk_widget_realize (GTK_WIDGET (ptr));
-
- gdk_threads_leave ();
-}
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c
index cb2c87238..7ce1185a4 100644
--- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c
@@ -242,14 +242,7 @@ clipboard_get_func (GtkClipboard *clipboard,
pixbuf = cp_gtk_image_get_pixbuf (env, gtkimage);
if (pixbuf != NULL)
- {
- gtk_selection_data_set_pixbuf (selection, pixbuf);
-
- /* if the GtkImage is offscreen, this is a temporary pixbuf
- which should be thrown out. */
- if(cp_gtk_image_is_offscreen (env, gtkimage) == JNI_TRUE)
- gdk_pixbuf_unref (pixbuf);
- }
+ gtk_selection_data_set_pixbuf (selection, pixbuf);
}
else if (info == URI_TARGET)
{
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c
index b0d4ab9b0..4cd80a73f 100644
--- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c
@@ -204,6 +204,7 @@ Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetCursorUnlocked
{
void *ptr;
GtkWidget *widget;
+ GdkWindow *win;
GdkCursorType gdk_cursor_type;
GdkCursor *gdk_cursor;
@@ -255,16 +256,20 @@ Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetCursorUnlocked
}
widget = get_widget(GTK_WIDGET(ptr));
-
+
+ win = widget->window;
+ if ((widget->window) == NULL)
+ win = GTK_WIDGET(ptr)->window;
+
if (image == NULL)
gdk_cursor = gdk_cursor_new (gdk_cursor_type);
else
gdk_cursor
- = gdk_cursor_new_from_pixbuf (gdk_drawable_get_display (widget->window),
+ = gdk_cursor_new_from_pixbuf (gdk_drawable_get_display (win),
cp_gtk_image_get_pixbuf (env, image),
x, y);
- gdk_window_set_cursor (widget->window, gdk_cursor);
+ gdk_window_set_cursor (win, gdk_cursor);
gdk_cursor_unref (gdk_cursor);
/* Make sure the cursor is replaced on screen. */
@@ -749,6 +754,20 @@ Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetForeground
}
JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkComponentPeer_realize (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ gtk_widget_realize (GTK_WIDGET (ptr));
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkComponentPeer_setVisibleNative
(JNIEnv *env, jobject obj, jboolean visible)
{
@@ -793,30 +812,6 @@ Java_gnu_java_awt_peer_gtk_GtkComponentPeer_isEnabled
}
JNIEXPORT jboolean JNICALL
-Java_gnu_java_awt_peer_gtk_GtkComponentPeer_isRealized
- (JNIEnv *env, jobject obj)
-{
- void *ptr;
- jboolean ret_val;
-
- gdk_threads_enter ();
-
- ptr = NSA_GET_PTR (env, obj);
-
- if (ptr == NULL)
- {
- gdk_threads_leave ();
- return FALSE;
- }
-
- ret_val = GTK_WIDGET_REALIZED (get_widget(GTK_WIDGET (ptr)));
-
- gdk_threads_leave ();
-
- return ret_val;
-}
-
-JNIEXPORT jboolean JNICALL
Java_gnu_java_awt_peer_gtk_GtkComponentPeer_modalHasGrab
(JNIEnv *env __attribute__((unused)), jclass clazz __attribute__((unused)))
{
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c
index c60f48f51..766964314 100644
--- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c
@@ -186,10 +186,5 @@ Java_gnu_java_awt_peer_gtk_GtkFramePeer_nativeSetIconImage
gtk_window_set_icon (GTK_WINDOW (ptr), pixbuf);
- /* if the GtkImage is offscreen, this is a temporary pixbuf which should
- be thrown out. */
- if(cp_gtk_image_is_offscreen (env, gtkimage) == JNI_TRUE)
- gdk_pixbuf_unref (pixbuf);
-
gdk_threads_leave ();
}
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c
index 92bc09edd..24e3d6317 100644
--- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c
@@ -37,8 +37,10 @@ exception statement from your version. */
#include "jcl.h"
#include "gtkpeer.h"
+#include <cairo-xlib.h>
+#include <gdk/gdkx.h>
+
#include "gnu_java_awt_peer_gtk_GtkImage.h"
-#include <gdk-pixbuf/gdk-pixbuf.h>
/* The constant fields in java.awt.Image */
#define SCALE_DEFAULT 1
@@ -49,13 +51,11 @@ exception statement from your version. */
/* local stuff */
static GdkInterpType mapHints(jint hints);
-static jboolean offScreen (JNIEnv * env, jobject obj);
-static void *getData (JNIEnv * env, jobject obj);
static void createRawData (JNIEnv * env, jobject obj, void *ptr);
static void setWidthHeight (JNIEnv * env, jobject obj, int width, int height);
/**
- * Loads a pixmap from a file.
+ * Loads a pixbuf from a file.
*/
JNIEXPORT jboolean JNICALL
Java_gnu_java_awt_peer_gtk_GtkImage_loadPixbuf
@@ -135,7 +135,7 @@ Java_gnu_java_awt_peer_gtk_GtkImage_createFromPixbuf
(JNIEnv *env, jobject obj)
{
int width, heigth;
- GdkPixbuf *pixbuf = (GdkPixbuf *) getData (env, obj);
+ GdkPixbuf *pixbuf = cp_gtk_image_get_pixbuf (env, obj);
width = gdk_pixbuf_get_width (pixbuf);
heigth = gdk_pixbuf_get_height (pixbuf);
setWidthHeight(env, obj, width, heigth);
@@ -154,6 +154,8 @@ Java_gnu_java_awt_peer_gtk_GtkImage_getPixels(JNIEnv *env, jobject obj)
jint *result_array_iter, *dst;
int i,j;
+ gdk_threads_enter ();
+
pixbuf = cp_gtk_image_get_pixbuf (env, obj);
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
@@ -190,11 +192,9 @@ Java_gnu_java_awt_peer_gtk_GtkImage_getPixels(JNIEnv *env, jobject obj)
}
}
- if (offScreen (env, obj) == JNI_TRUE)
- gdk_pixbuf_unref (pixbuf);
-
(*env)->ReleaseIntArrayElements (env, result_array, result_array_iter, 0);
+ gdk_threads_leave ();
return result_array;
}
@@ -206,7 +206,7 @@ JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkImage_setPixels(JNIEnv *env, jobject obj,
jintArray pixels)
{
- GdkPixbuf *pixbuf = (GdkPixbuf *)getData (env, obj);
+ GdkPixbuf *pixbuf = cp_gtk_image_get_pixbuf (env, obj);
int width, height, rowstride;
guchar *pixeldata;
jint *src_array_iter, *src;
@@ -231,10 +231,10 @@ Java_gnu_java_awt_peer_gtk_GtkImage_setPixels(JNIEnv *env, jobject obj,
}
/**
- * Allocates a Gtk Pixbuf or Pixmap.
+ * Allocates a Gtk Pixbuf
*/
JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GtkImage_createPixmap(JNIEnv *env, jobject obj)
+Java_gnu_java_awt_peer_gtk_GtkImage_createPixbuf(JNIEnv *env, jobject obj)
{
int width, height;
jclass cls;
@@ -249,35 +249,58 @@ Java_gnu_java_awt_peer_gtk_GtkImage_createPixmap(JNIEnv *env, jobject obj)
g_assert (field != 0);
height = (*env)->GetIntField (env, obj, field);
- if (offScreen (env, obj) == JNI_FALSE)
- createRawData (env, obj, gdk_pixbuf_new (GDK_COLORSPACE_RGB,
- TRUE,
- 8,
- width,
- height));
- else
- createRawData (env, obj, gdk_pixmap_new (NULL, width, height,
- gdk_rgb_get_visual ()->depth));
+ createRawData (env, obj, gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+ TRUE,
+ 8,
+ width,
+ height));
+}
+
+/**
+ * Allocates a Gtk Pixbuf
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkImage_initFromBuffer(JNIEnv *env, jobject obj,
+ jlong bufferPointer)
+{
+ int width, height;
+ jclass cls;
+ jfieldID field;
+ GdkPixbuf *pixbuf;
+ const guchar *bp = JLONG_TO_PTR(const guchar, bufferPointer);
+
+ g_assert(bp != NULL);
+ cls = (*env)->GetObjectClass( env, obj );
+ field = (*env)->GetFieldID( env, cls, "width", "I" );
+ g_assert( field != 0 );
+ width = (*env)->GetIntField( env, obj, field );
+
+ field = (*env)->GetFieldID( env, cls, "height", "I" );
+ g_assert( field != 0 );
+ height = (*env)->GetIntField( env, obj, field );
+
+ pixbuf = gdk_pixbuf_new_from_data( bp,
+ GDK_COLORSPACE_RGB, TRUE, 8,
+ width, height, width * 4, NULL, NULL );
+ g_assert( pixbuf != NULL );
+ createRawData( env, obj, pixbuf );
}
/**
- * Frees the Gtk Pixmap.
+ * Frees the Gtk Pixbuf.
*/
JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GtkImage_freePixmap(JNIEnv *env, jobject obj)
+Java_gnu_java_awt_peer_gtk_GtkImage_freePixbuf(JNIEnv *env, jobject obj)
{
- if (offScreen (env, obj) == JNI_FALSE)
- gdk_pixbuf_unref ((GdkPixbuf *)getData (env, obj));
- else
- g_object_unref ((GdkPixmap *)getData (env, obj));
+ gdk_pixbuf_unref (cp_gtk_image_get_pixbuf (env, obj));
}
/**
- * Sets this pixmap to a scaled version of the source pixmap.
+ * Sets this to a scaled version of the original pixbuf
* width and height of the destination GtkImage must be set.
*/
JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GtkImage_createScaledPixmap(JNIEnv *env,
+Java_gnu_java_awt_peer_gtk_GtkImage_createScaledPixbuf(JNIEnv *env,
jobject destination,
jobject source,
jint hints)
@@ -304,251 +327,25 @@ Java_gnu_java_awt_peer_gtk_GtkImage_createScaledPixmap(JNIEnv *env,
width, height,
mapHints(hints));
- if (offScreen (env, source) == JNI_TRUE)
- gdk_pixbuf_unref (pixbuf);
-
createRawData (env, destination, (void *)dst);
}
/**
- * Draws the pixbuf at x, y, scaled to width and height and
- * optionally composited with a given background color.
- */
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GtkImage_drawPixelsScaled
- (JNIEnv *env, jobject obj, jobject gc_obj,
- jint bg_red, jint bg_green, jint bg_blue,
- jint x, jint y, jint width, jint height, jboolean composite)
-{
- GdkPixbuf* dst;
- struct graphics *g;
- guint32 bgColor;
-
- gdk_threads_enter ();
-
- if (width <= 0 || height <= 0)
- {
- gdk_threads_leave ();
- return;
- }
-
- bgColor = ((bg_red & 0xFF) << 16) |
- ((bg_green & 0xFF) << 8) | (bg_blue & 0xFF);
-
- g = (struct graphics *) NSA_GET_G_PTR (env, gc_obj);
-
- if (!g || !GDK_IS_DRAWABLE (g->drawable))
- {
- gdk_threads_leave ();
- return;
- }
-
- if (offScreen (env, obj) == JNI_FALSE)
- {
- GdkPixbuf* pixbuf = (GdkPixbuf *)getData (env, obj);
-
- /* Scale and composite the image */
- if (composite == JNI_TRUE)
- dst = gdk_pixbuf_composite_color_simple (pixbuf,
- width,
- height,
- GDK_INTERP_BILINEAR,
- 255,
- width,
- bgColor,
- bgColor);
- else
- dst = gdk_pixbuf_scale_simple(pixbuf,
- width, height,
- GDK_INTERP_BILINEAR);
-
- gdk_draw_pixbuf (g->drawable,
- g->gc,
- dst,
- 0, 0,
- x + g->x_offset, y + g->y_offset,
- width, height,
- GDK_RGB_DITHER_NORMAL, 0, 0);
- gdk_pixbuf_unref (dst);
-
- } else {
- /* Get a pixmap */
- GdkPixmap* pixmap = (GdkPixmap *)getData (env, obj);
- gdk_draw_drawable (g->drawable,
- g->gc,
- pixmap,
- 0, 0, /* src x,y */
- x + g->x_offset, y + g->y_offset,
- width, height);
- }
-
- gdk_threads_leave ();
-}
-
-/**
- * Draws the pixbuf at x, y, scaled to width and height and
- * optionally composited and/or flipped with a given background color.
- */
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GtkImage_drawPixelsScaledFlipped
-(JNIEnv *env, jobject obj, jobject gc_obj,
- jint bg_red, jint bg_green, jint bg_blue,
-#if GTK_MINOR_VERSION > 4
- jboolean flipx, jboolean flipy,
-#else
- jboolean flipx __attribute__((unused)),
- jboolean flipy __attribute__((unused)),
-#endif
- jint srcx, jint srcy, jint srcwidth, jint srcheight,
- jint dstx, jint dsty, jint dstwidth, jint dstheight,
- jboolean composite)
-{
- GdkPixbuf *pixbuf;
- GdkPixbuf *tmp, *dst;
- struct graphics *g;
- guint32 bgColor;
-
- gdk_threads_enter ();
-
- if (srcwidth <= 0 || srcheight <= 0
- || dstwidth <= 0 || dstheight <= 0)
- {
- gdk_threads_leave ();
- return;
- }
-
- bgColor = ((bg_red & 0xFF) << 16) |
- ((bg_green & 0xFF) << 8) | (bg_blue & 0xFF);
-
- g = (struct graphics *) NSA_GET_G_PTR (env, gc_obj);
-
- if (!g || !GDK_IS_DRAWABLE (g->drawable))
- {
- gdk_threads_leave ();
- return;
- }
-
- if (offScreen (env, obj) == JNI_FALSE)
- {
- pixbuf = (GdkPixbuf *)getData (env, obj);
-
- /* Get the source area */
- tmp = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
- TRUE,
- 8,
- srcwidth,
- srcheight);
-
- gdk_pixbuf_copy_area (pixbuf,
- srcx, srcy,
- srcwidth, srcheight,
- tmp,
- 0, 0); /* dst x , dst y */
- } else {
- /* Get a pixbuf from the pixmap */
- GdkDrawable *pixmap = (GdkDrawable *)getData(env, obj);
- tmp = gdk_pixbuf_get_from_drawable (NULL,
- pixmap,
- gdk_drawable_get_colormap( pixmap ),
- srcx, srcy,
- 0, 0, /* dst x , dst y */
- srcwidth, srcheight);
- }
-
- /* FIXME: This #if should be discarded once I feel comfortable about
- GTK 2.6 dependence */
-#if GTK_MINOR_VERSION > 4
- /* Flip it if necessary. */
- if (flipx == JNI_TRUE)
- {
- GdkPixbuf *tmp2 = gdk_pixbuf_flip (tmp, TRUE);
- gdk_pixbuf_unref (tmp);
- tmp = tmp2;
- }
- if (flipy == JNI_TRUE)
- {
- GdkPixbuf *tmp2 = gdk_pixbuf_flip (tmp, FALSE);
- gdk_pixbuf_unref (tmp);
- tmp = tmp2;
- }
-#endif
-
- /* Scale and composite the image */
- if (composite == JNI_TRUE)
- dst = gdk_pixbuf_composite_color_simple (tmp,
- dstwidth,
- dstheight,
- GDK_INTERP_BILINEAR,
- 255,
- dstwidth,
- bgColor,
- bgColor);
- else
- dst = gdk_pixbuf_scale_simple(tmp,
- dstwidth, dstheight,
- GDK_INTERP_BILINEAR);
- gdk_pixbuf_unref (tmp);
-
- gdk_draw_pixbuf (g->drawable,
- g->gc,
- dst,
- 0, 0,
- dstx + g->x_offset, dsty + g->y_offset,
- dstwidth, dstheight,
- GDK_RGB_DITHER_NORMAL, 0, 0);
-
- gdk_pixbuf_unref (dst);
-
- gdk_threads_leave ();
-}
-
-/**
* Used by GtkFramePeer
*/
GdkPixbuf *cp_gtk_image_get_pixbuf (JNIEnv *env, jobject obj)
{
- int width, height;
- GdkPixbuf *pixbuf;
- GdkPixmap* pixmap;
jclass cls;
- jfieldID field;
-
- if (offScreen (env, obj) == JNI_FALSE)
- return (GdkPixbuf *)getData (env, obj);
+ jfieldID data_fid;
+ jobject data;
cls = (*env)->GetObjectClass (env, obj);
- field = (*env)->GetFieldID (env, cls, "width", "I");
- g_assert (field != 0);
- width = (*env)->GetIntField (env, obj, field);
-
- field = (*env)->GetFieldID (env, cls, "height", "I");
- g_assert (field != 0);
- height = (*env)->GetIntField (env, obj, field);
-
- /* Get a pixmap */
- pixmap = (GdkPixmap *)getData (env, obj);
- pixbuf = gdk_pixbuf_get_from_drawable (NULL,
- pixmap,
- gdk_drawable_get_colormap( pixmap ),
- 0, 0, /* src x , src y */
- 0, 0, /* dst x , dst y */
- width, height);
- return pixbuf;
-}
-
-/**
- * Used by GdkGraphics
- */
-GdkPixmap *cp_gtk_image_get_pixmap (JNIEnv *env, jobject obj)
-{
- if (offScreen (env, obj) == JNI_FALSE)
- return NULL;
- return (GdkPixmap *)getData (env, obj);
-}
+ data_fid = (*env)->GetFieldID (env, cls, "pixbuf",
+ "Lgnu/classpath/Pointer;");
+ g_assert (data_fid != 0);
+ data = (*env)->GetObjectField (env, obj, data_fid);
-jboolean cp_gtk_image_is_offscreen (JNIEnv *env, jobject obj)
-{
- return offScreen(env, obj);
+ return (GdkPixbuf *)JCL_GetRawData (env, data);
}
/**
@@ -593,18 +390,6 @@ static void setWidthHeight (JNIEnv * env, jobject obj, int width, int height)
(*env)->SetIntField (env, obj, field, (jint)height);
}
-/* Returns the value of the offScreen field. */
-static jboolean offScreen (JNIEnv *env, jobject obj)
-{
- jclass cls;
- jfieldID field;
-
- cls = (*env)->GetObjectClass (env, obj);
- field = (*env)->GetFieldID (env, cls, "offScreen", "Z");
- g_assert (field != 0);
- return (*env)->GetBooleanField (env, obj, field);
-}
-
/* Store and get the pixbuf pointer */
static void
createRawData (JNIEnv * env, jobject obj, void *ptr)
@@ -614,7 +399,7 @@ createRawData (JNIEnv * env, jobject obj, void *ptr)
jfieldID data_fid;
cls = (*env)->GetObjectClass (env, obj);
- data_fid = (*env)->GetFieldID (env, cls, "pixmap",
+ data_fid = (*env)->GetFieldID (env, cls, "pixbuf",
"Lgnu/classpath/Pointer;");
g_assert (data_fid != 0);
@@ -623,18 +408,3 @@ createRawData (JNIEnv * env, jobject obj, void *ptr)
(*env)->SetObjectField (env, obj, data_fid, data);
}
-static void *
-getData (JNIEnv * env, jobject obj)
-{
- jclass cls;
- jfieldID data_fid;
- jobject data;
-
- cls = (*env)->GetObjectClass (env, obj);
- data_fid = (*env)->GetFieldID (env, cls, "pixmap",
- "Lgnu/classpath/Pointer;");
- g_assert (data_fid != 0);
- data = (*env)->GetObjectField (env, obj, data_fid);
-
- return JCL_GetRawData (env, data);
-}
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c
index b14330e5f..c966f6331 100644
--- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c
@@ -185,10 +185,6 @@ Java_gnu_java_awt_peer_gtk_GtkToolkit_gtkInit (JNIEnv *env,
old_glog_func = g_log_set_default_handler (&glog_func, NULL);
#endif
-#if GTK_CAIRO
- cp_gtk_graphics2d_init_jni ();
-#endif
- cp_gtk_graphics_init_jni ();
cp_gtk_button_init_jni ();
cp_gtk_checkbox_init_jni ();
cp_gtk_choice_init_jni ();
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkVolatileImage.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkVolatileImage.c
new file mode 100644
index 000000000..0234943b2
--- /dev/null
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkVolatileImage.c
@@ -0,0 +1,190 @@
+/* gnu_java_awt_peer_gtk_VolatileImage.c
+ 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. */
+
+#include "jcl.h"
+#include "gtkpeer.h"
+#include <gdk/gdkx.h>
+#include <gdk/gdktypes.h>
+#include <gdk/gdkprivate.h>
+#include <gdk/gdkx.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gdk-pixbuf/gdk-pixdata.h>
+
+#include "gnu_java_awt_peer_gtk_GtkVolatileImage.h"
+#include "cairographics2d.h"
+
+/* prototypes */
+static void *getNativeObject( JNIEnv *env, jobject obj );
+/* static void setNativeObject( JNIEnv *env, jobject obj, void *ptr ); */
+
+GdkPixmap *cp_gtk_get_pixmap( JNIEnv *env, jobject obj);
+
+/**
+ * Creates a cairo surface, ARGB32, native ordering, premultiplied alpha.
+ */
+JNIEXPORT jlong JNICALL
+Java_gnu_java_awt_peer_gtk_GtkVolatileImage_init (JNIEnv *env,
+ jobject obj __attribute__ ((__unused__)),
+ jobject peer,
+ jint width, jint height)
+{
+ GtkWidget *widget = NULL;
+ GdkPixmap* pixmap;
+ void *ptr = NULL;
+
+ gdk_threads_enter();
+
+ if( peer != NULL )
+ {
+ ptr = NSA_GET_PTR (env, peer);
+ g_assert (ptr != NULL);
+
+ widget = GTK_WIDGET (ptr);
+ g_assert (widget != NULL);
+ pixmap = gdk_pixmap_new( widget->window, width, height, -1 );
+ }
+ else
+ pixmap = gdk_pixmap_new( NULL, width, height, 16 );
+
+ gdk_threads_leave();
+
+ g_assert( pixmap != NULL );
+
+ return PTR_TO_JLONG( pixmap );
+}
+
+/**
+ * Destroy the surface
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkVolatileImage_destroy (JNIEnv *env, jobject obj)
+{
+ GdkPixmap* pixmap = getNativeObject(env, obj);
+ if( pixmap != NULL )
+ {
+ gdk_threads_enter();
+ g_object_unref( pixmap );
+ gdk_threads_leave();
+ }
+}
+
+/**
+ * Gets all pixels in an array
+ */
+JNIEXPORT jintArray JNICALL
+Java_gnu_java_awt_peer_gtk_GtkVolatileImage_getPixels
+(JNIEnv *env, jobject obj)
+{
+ /* jint *pixeldata, *jpixdata; */
+ jint *jpixdata;
+ GdkPixmap *pixmap;
+ jintArray jpixels;
+ int width, height, depth, size;
+ jclass cls;
+ jfieldID field;
+
+ cls = (*env)->GetObjectClass (env, obj);
+ field = (*env)->GetFieldID (env, cls, "width", "I");
+ g_assert (field != 0);
+ width = (*env)->GetIntField (env, obj, field);
+
+ field = (*env)->GetFieldID (env, cls, "height", "I");
+ g_assert (field != 0);
+ height = (*env)->GetIntField (env, obj, field);
+
+ pixmap = GDK_PIXMAP(getNativeObject(env, obj));
+ g_assert(pixmap != NULL);
+
+ gdk_threads_enter();
+
+ /* get depth in bytes */
+ depth = gdk_drawable_get_depth( pixmap ) >> 3;
+ size = width * height * 4;
+ jpixels = (*env)->NewIntArray ( env, size );
+ jpixdata = (*env)->GetIntArrayElements (env, jpixels, NULL);
+ /* memcpy (jpixdata, pixeldata, size * sizeof( jint )); */
+
+ (*env)->ReleaseIntArrayElements (env, jpixels, jpixdata, 0);
+
+ gdk_threads_leave();
+
+ return jpixels;
+}
+
+/**
+ * Update the pixels.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkVolatileImage_update
+(JNIEnv *env, jobject obj, jobject gtkimage)
+{
+ GdkPixmap *pixmap = getNativeObject(env, obj);
+ GdkPixbuf *pixbuf;
+
+ gdk_threads_enter();
+ g_assert( pixmap != NULL );
+
+ pixbuf = cp_gtk_image_get_pixbuf (env, gtkimage);
+ g_assert( pixbuf != NULL );
+
+ gdk_draw_pixbuf (pixmap, NULL, pixbuf,
+ 0, 0, 0, 0, /* src and dest x, y */
+ -1, -1, /* full width, height */
+ GDK_RGB_DITHER_NORMAL, 0, 0);
+ gdk_threads_leave();
+}
+
+GdkPixmap *cp_gtk_get_pixmap( JNIEnv *env, jobject obj)
+{
+ return (GdkPixmap *)getNativeObject(env, obj);
+}
+
+/**
+ * Gets the native object field.
+ */
+static void *
+getNativeObject( JNIEnv *env, jobject obj )
+{
+ jclass cls;
+ jlong value;
+ jfieldID nofid;
+ cls = (*env)->GetObjectClass( env, obj );
+ nofid = (*env)->GetFieldID( env, cls, "nativePointer", "J" );
+ value = (*env)->GetLongField( env, obj, nofid );
+ (*env)->DeleteLocalRef( env, cls );
+ return JLONG_TO_PTR(void, value);
+}
diff --git a/native/jni/gtk-peer/gtkpeer.h b/native/jni/gtk-peer/gtkpeer.h
index 9a1590b81..065d20608 100644
--- a/native/jni/gtk-peer/gtkpeer.h
+++ b/native/jni/gtk-peer/gtkpeer.h
@@ -36,12 +36,14 @@ obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
+#include <cairo.h>
#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <config.h>
#include "native_state.h"
+#include <gdk-pixbuf/gdk-pixbuf.h>
#include <jni.h>
@@ -54,6 +56,7 @@ exception statement from your version. */
extern struct state_table *cp_gtk_native_state_table;
extern struct state_table *cp_gtk_native_global_ref_table;
+extern struct state_table *cp_gtk_native_graphics2d_state_table;
#define NSA_INIT(env, clazz) \
do {cp_gtk_native_state_table = cp_gtk_init_state_table (env, clazz); \
@@ -83,34 +86,21 @@ extern struct state_table *cp_gtk_native_global_ref_table;
(*env)->DeleteGlobalRef (env, *globRefPtr); \
free (globRefPtr);} while (0)
-extern struct state_table *cp_gtk_native_graphics_state_table;
+#define NSA_G2D_INIT(env, clazz) \
+ cp_gtk_native_graphics2d_state_table = cp_gtk_init_state_table (env, clazz)
-#define NSA_G_INIT(env, clazz) \
- cp_gtk_native_graphics_state_table = cp_gtk_init_state_table (env, clazz)
+#define NSA_GET_G2D_PTR(env, obj) \
+ cp_gtk_get_state (env, obj, cp_gtk_native_graphics2d_state_table)
-#define NSA_GET_G_PTR(env, obj) \
- cp_gtk_get_state (env, obj, cp_gtk_native_graphics_state_table)
+#define NSA_SET_G2D_PTR(env, obj, ptr) \
+ cp_gtk_set_state (env, obj, cp_gtk_native_graphics2d_state_table, (void *)ptr)
-#define NSA_SET_G_PTR(env, obj, ptr) \
- cp_gtk_set_state (env, obj, cp_gtk_native_graphics_state_table, (void *)ptr)
-
-#define NSA_DEL_G_PTR(env, obj) \
- cp_gtk_remove_state_slot (env, obj, cp_gtk_native_graphics_state_table)
+#define NSA_DEL_G2D_PTR(env, obj) \
+ cp_gtk_remove_state_slot (env, obj, cp_gtk_native_graphics2d_state_table)
#define SWAPU32(w) \
(((w) << 24) | (((w) & 0xff00) << 8) | (((w) >> 8) & 0xff00) | ((w) >> 24))
-struct graphics
-{
- GdkDrawable *drawable;
- GdkGC *gc;
- GdkColormap *cm;
- PangoFontDescription *pango_font;
- PangoContext *pango_context;
- PangoLayout *pango_layout;
- jint x_offset, y_offset;
-};
-
/* New-style event masks. */
#define AWT_BUTTON1_DOWN_MASK (1 << 10)
#define AWT_BUTTON2_DOWN_MASK (1 << 11)
@@ -192,14 +182,12 @@ jint cp_gtk_state_to_awt_mods (guint state);
/* Image helpers */
GdkPixbuf *cp_gtk_image_get_pixbuf (JNIEnv *env, jobject obj);
-GdkPixmap *cp_gtk_image_get_pixmap (JNIEnv *env, jobject obj);
-jboolean cp_gtk_image_is_offscreen (JNIEnv *env, jobject obj);
+
+/* Component Graphics helpers */
+void cp_gtk_grab_current_drawable(GtkWidget *widget, GdkDrawable **draw,
+ GdkWindow **win);
/* JNI initialization functions */
-#if GTK_CAIRO
-void cp_gtk_graphics2d_init_jni (void);
-#endif
-void cp_gtk_graphics_init_jni (void);
void cp_gtk_button_init_jni (void);
void cp_gtk_checkbox_init_jni (void);
void cp_gtk_choice_init_jni (void);
@@ -221,6 +209,8 @@ void cp_gtk_textcomponent_connect_signals (GObject *ptr, jobject *gref);
/* Debugging */
void cp_gtk_print_current_thread (void);
+GdkPixmap *cp_gtk_get_pixmap( JNIEnv *env, jobject obj);
+
#define SYNCHRONIZE_GDK 0
#define DEBUG_LOCKING 0
diff --git a/native/jni/java-net/Makefile.am b/native/jni/java-net/Makefile.am
index 854c624d1..b743f2ffe 100644
--- a/native/jni/java-net/Makefile.am
+++ b/native/jni/java-net/Makefile.am
@@ -12,12 +12,14 @@ libjavanet_la_SOURCES = javanet.c \
javanet.h \
java_net_VMInetAddress.c \
java_net_VMNetworkInterface.c \
+ java_net_VMURLConnection.c \
gnu_java_net_VMPlainDatagramSocketImpl.c \
gnu_java_net_VMPlainSocketImpl.c \
$(local_sources)
libjavanet_la_LIBADD = $(top_builddir)/native/jni/classpath/jcl.lo \
- $(top_builddir)/native/jni/native-lib/libclasspathnative.la
+ $(top_builddir)/native/jni/native-lib/libclasspathnative.la \
+ $(LIBMAGIC)
AM_LDFLAGS = @CLASSPATH_MODULE@
AM_CPPFLAGS = @CLASSPATH_INCLUDES@
diff --git a/native/jni/java-net/java_net_VMURLConnection.c b/native/jni/java-net/java_net_VMURLConnection.c
new file mode 100644
index 000000000..52fae0ccb
--- /dev/null
+++ b/native/jni/java-net/java_net_VMURLConnection.c
@@ -0,0 +1,102 @@
+/* VMURLConnection.c - native bits for URLConnection
+ 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. */
+
+#include <config.h>
+
+#include <java_net_VMURLConnection.h>
+
+#ifdef HAVE_MAGIC_H
+
+#include <magic.h>
+
+static magic_t cookie;
+
+#endif /* HAVE_MAGIC_H */
+
+void
+Java_java_net_VMURLConnection_init (JNIEnv *env __attribute__ ((__unused__)),
+ jclass klass __attribute__ ((__unused__)))
+{
+#ifdef HAVE_MAGIC_H
+ cookie = magic_open (MAGIC_MIME);
+ if (cookie == (magic_t) NULL)
+ return;
+ if (magic_load (cookie, NULL) == -1)
+ {
+ magic_close (cookie);
+ cookie = (magic_t) NULL;
+ }
+#endif /* HAVE_MAGIC_H */
+}
+
+#ifdef HAVE_MAGIC_H
+jstring
+Java_java_net_VMURLConnection_guessContentTypeFromBuffer (JNIEnv *env,
+ jclass klass
+ __attribute__ ((__unused__)),
+ jbyteArray bytes,
+ jint valid)
+{
+ jbyte *elements;
+ const char *result;
+
+ if (cookie == (magic_t) NULL)
+ return NULL;
+
+ elements = (*env)->GetByteArrayElements (env, bytes, NULL);
+ result = magic_buffer (cookie, elements, valid);
+
+ /* The mode we use doesn't matter, since we don't change the array. */
+ (*env)->ReleaseByteArrayElements (env, bytes, elements, JNI_ABORT);
+
+ if (result == NULL)
+ return NULL;
+ return (*env)->NewStringUTF (env, result);
+#else
+jstring
+Java_java_net_VMURLConnection_guessContentTypeFromBuffer (JNIEnv *env
+ __attribute__ ((__unused__)),
+ jclass klass
+ __attribute__ ((__unused__)),
+ jbyteArray bytes
+ __attribute__ ((__unused__)),
+ jint valid
+ __attribute__ ((__unused__)))
+{
+ return NULL;
+#endif /* HAVE_MAGIC_H */
+}
diff --git a/native/jni/java-net/javanet.c b/native/jni/java-net/javanet.c
index 34a661a10..aa58a4e02 100644
--- a/native/jni/java-net/javanet.c
+++ b/native/jni/java-net/javanet.c
@@ -806,6 +806,9 @@ _javanet_accept (JNIEnv * env, jobject this, jobject impl)
}
while (result != CPNATIVE_OK);
+ /* Reset the inherited timeout. */
+ TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_TIMEOUT (newfd, 0, result);
+
/* Populate instance variables */
_javanet_set_int_field (env, impl, "gnu/java/net/PlainSocketImpl",
"native_fd", newfd);
diff --git a/native/jni/java-nio/Makefile.am b/native/jni/java-nio/Makefile.am
index 58d3e9506..800d25be6 100644
--- a/native/jni/java-nio/Makefile.am
+++ b/native/jni/java-nio/Makefile.am
@@ -1,6 +1,7 @@
nativeexeclib_LTLIBRARIES = libjavanio.la
libjavanio_la_SOURCES = gnu_java_nio_VMPipe.c \
+ gnu_java_nio_VMChannel.c \
gnu_java_nio_VMSelector.c \
gnu_java_nio_channels_FileChannelImpl.c \
gnu_java_nio_charset_iconv_IconvDecoder.c \
diff --git a/native/jni/java-nio/gnu_java_nio_VMChannel.c b/native/jni/java-nio/gnu_java_nio_VMChannel.c
new file mode 100644
index 000000000..5571bed27
--- /dev/null
+++ b/native/jni/java-nio/gnu_java_nio_VMChannel.c
@@ -0,0 +1,525 @@
+/* gnu_java_nio_VMChannel.c -
+ Copyright (C) 2003, 2004, 2005, 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. */
+
+
+#include <config.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/uio.h>
+#include <string.h>
+
+#include <jni.h>
+#include <jcl.h>
+
+#include "gnu_java_nio_VMChannel.h"
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif /* HAVE_FCNTL_H */
+
+#define IO_EXCEPTION "java/io/IOException"
+#define NON_READABLE_CHANNEL_EXCEPTION "java/nio/channels/NonReadableChannelException"
+#define NON_WRITABLE_CHANNEL_EXCEPTION "java/nio/channels/NonWritableChannelException"
+
+/*
+ * Limit to maximum of 16 buffers
+ */
+#define JCL_IOV_MAX 16
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+enum JCL_buffer_type { DIRECT, ARRAY, UNKNOWN };
+
+struct JCL_buffer
+{
+ enum JCL_buffer_type type;
+ jbyte *ptr;
+ jint offset;
+ jint position;
+ jint limit;
+ jint count;
+};
+
+jmethodID get_method_id(JNIEnv *, jclass, const char *, const char *);
+void JCL_print_buffer(JNIEnv *, struct JCL_buffer *);
+int JCL_init_buffer(JNIEnv *, struct JCL_buffer *, jobject);
+void JCL_release_buffer(JNIEnv *, struct JCL_buffer *, jobject, jint);
+void JCL_cleanup_buffers(JNIEnv *, struct JCL_buffer *, jint, jobjectArray, jint, jlong);
+
+static jfieldID address_fid;
+static jmethodID get_position_mid;
+static jmethodID set_position_mid;
+static jmethodID get_limit_mid;
+static jmethodID set_limit_mid;
+static jmethodID has_array_mid;
+static jmethodID array_mid;
+static jmethodID array_offset_mid;
+
+jmethodID
+get_method_id(JNIEnv *env, jclass clazz, const char *name,
+ const char *sig)
+{
+ jmethodID mid = (*env)->GetMethodID(env, clazz, name, sig);
+ if (mid == NULL)
+ {
+ JCL_ThrowException(env, "java/lang/InternalError", name);
+ return NULL;
+ }
+
+ return mid;
+}
+
+void
+JCL_print_buffer(JNIEnv *env __attribute__((__unused__)), struct JCL_buffer *buf)
+{
+ fprintf(stdout, "Buffer - type: %d, ptr: %p\n", buf->type, buf->ptr);
+ fflush(stdout);
+}
+
+
+int
+JCL_init_buffer(JNIEnv *env, struct JCL_buffer *buf, jobject bbuf)
+{
+ jobject address = (*env)->GetObjectField(env, bbuf, address_fid);
+
+ buf->position = (*env)->CallIntMethod(env, bbuf, get_position_mid);
+ buf->limit = (*env)->CallIntMethod(env, bbuf, get_limit_mid);
+ buf->offset = 0;
+ buf->count = 0;
+ buf->type = UNKNOWN;
+
+ if (address != NULL)
+ {
+ buf->ptr = (jbyte *) JCL_GetRawData(env, address);
+ buf->type = DIRECT;
+ (*env)->DeleteLocalRef(env, address);
+ }
+ else
+ {
+ jboolean has_array;
+ has_array = (*env)->CallBooleanMethod(env, bbuf, has_array_mid);
+
+ if (has_array == JNI_TRUE)
+ {
+ jbyteArray arr;
+ buf->offset = (*env)->CallIntMethod(env, bbuf, array_offset_mid);
+ arr = (*env)->CallObjectMethod(env, bbuf, array_mid);
+ buf->ptr = (*env)->GetByteArrayElements(env, arr, 0);
+ buf->type = ARRAY;
+ (*env)->DeleteLocalRef(env, arr);
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+void
+JCL_release_buffer(JNIEnv *env, struct JCL_buffer *buf, jobject bbuf,
+ jint action)
+{
+ jbyteArray arr;
+
+ /* Set the position to the appropriate value */
+ if (buf->count > 0)
+ {
+ jobject bbufTemp;
+ bbufTemp = (*env)->CallObjectMethod(env, bbuf, set_position_mid,
+ buf->position + buf->count);
+ (*env)->DeleteLocalRef(env, bbufTemp);
+ }
+
+ switch (buf->type)
+ {
+ case DIRECT:
+ break;
+ case ARRAY:
+ arr = (*env)->CallObjectMethod(env, bbuf, array_mid);
+ (*env)->ReleaseByteArrayElements(env, arr, buf->ptr, action);
+ (*env)->DeleteLocalRef(env, arr);
+ break;
+ case UNKNOWN:
+ /* TODO: Handle buffers that are not direct or array backed */
+ break;
+ }
+}
+
+void
+JCL_cleanup_buffers(JNIEnv *env,
+ struct JCL_buffer *bi_list,
+ jint vec_len,
+ jobjectArray bbufs,
+ jint offset,
+ jlong num_bytes)
+{
+ jint i;
+
+ /* Update all of the bbufs with the approriate information */
+ for (i = 0; i < vec_len; i++)
+ {
+ struct JCL_buffer* buf;
+ jobject bbuf;
+
+ buf = &bi_list[i];
+ bbuf = (*env)->GetObjectArrayElement(env, bbufs, offset + i);
+
+ if (num_bytes > (buf->limit - buf->position))
+ buf->count = (buf->limit - buf->position);
+ else
+ buf->count = num_bytes;
+
+ num_bytes -= buf->count;
+
+ JCL_release_buffer(env, buf, bbuf, JNI_ABORT);
+ (*env)->DeleteLocalRef(env, bbuf);
+ }
+}
+
+
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_VMChannel_initIDs (JNIEnv *env,
+ jclass clazz __attribute__ ((__unused__)))
+{
+ jclass bufferClass = JCL_FindClass(env, "java/nio/Buffer");
+ jclass byteBufferClass = JCL_FindClass(env, "java/nio/ByteBuffer");
+
+ address_fid = (*env)->GetFieldID(env, bufferClass, "address",
+ "Lgnu/classpath/Pointer;");
+ if (address_fid == NULL)
+ {
+ JCL_ThrowException(env, "java/lang/InternalError",
+ "Unable to find internal field");
+ return;
+ }
+
+ get_position_mid = get_method_id(env, bufferClass, "position", "()I");
+ set_position_mid = get_method_id(env, bufferClass, "position",
+ "(I)Ljava/nio/Buffer;");
+ get_limit_mid = get_method_id(env, bufferClass, "limit", "()I");
+ set_limit_mid = get_method_id(env, bufferClass, "limit",
+ "(I)Ljava/nio/Buffer;");
+ has_array_mid = get_method_id(env, byteBufferClass, "hasArray", "()Z");
+ array_mid = get_method_id(env, byteBufferClass, "array", "()[B");
+ array_offset_mid = get_method_id(env, byteBufferClass, "arrayOffset", "()I");
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_VMChannel_setBlocking (JNIEnv *env,
+ jobject o __attribute__ ((__unused__)),
+ jint fd,
+ jboolean blocking)
+{
+ int opts;
+
+ opts = fcntl(fd, F_GETFL);
+ if (opts < 0)
+ {
+ JCL_ThrowException(env, IO_EXCEPTION,
+ "Failed to get flags for file desriptor");
+ return;
+ }
+
+ if (blocking)
+ opts |= O_NONBLOCK;
+ else
+ opts &= ~(O_NONBLOCK);
+
+ opts = fcntl(fd, F_SETFL, opts);
+
+ if (opts < 0)
+ {
+ JCL_ThrowException(env, IO_EXCEPTION,
+ "Failed to set flags for file desriptor");
+ return;
+ }
+}
+
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_VMChannel_read (JNIEnv *env,
+ jobject o __attribute__ ((__unused__)),
+ jint fd,
+ jobject bbuf)
+{
+ jint len;
+ ssize_t result;
+ struct JCL_buffer buf;
+
+ if (JCL_init_buffer(env, &buf, bbuf) < 0)
+ {
+ /* TODO: Rethrown exception */
+ JCL_ThrowException (env, IO_EXCEPTION, "Buffer initialisation failed");
+ return -1;
+ }
+
+ len = buf.limit - buf.position;
+
+ result = read(fd, &(buf.ptr[buf.position + buf.offset]), len);
+ buf.count = result;
+
+ if (result == 0)
+ result = -1; /* End Of File */
+ else if (result == -1)
+ {
+ buf.count = 0;
+ if (errno == EAGAIN) /* Non-blocking */
+ result = 0;
+ else if (errno == EBADF) /* Bad fd */
+ {
+ JCL_release_buffer(env, &buf, bbuf, JNI_ABORT);
+ JCL_ThrowException (env, NON_READABLE_CHANNEL_EXCEPTION,
+ strerror(errno));
+ return -1;
+ }
+ else
+ {
+ JCL_release_buffer(env, &buf, bbuf, JNI_ABORT);
+ JCL_ThrowException (env, IO_EXCEPTION, strerror(errno));
+ return -1;
+ }
+ }
+ else
+
+ JCL_release_buffer(env, &buf, bbuf, JNI_COMMIT);
+
+ return result;
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_VMChannel_write (JNIEnv *env,
+ jobject o __attribute__ ((__unused__)),
+ jint fd,
+ jobject bbuf)
+{
+ jint len;
+ ssize_t result;
+ struct JCL_buffer buf;
+
+ if (JCL_init_buffer(env, &buf, bbuf) < 0)
+ {
+ /* TODO: Rethrown exception */
+ JCL_ThrowException (env, IO_EXCEPTION, "Buffer initialisation failed");
+ return -1;
+ }
+
+ len = buf.limit - buf.position;
+
+ result = write(fd, &(buf.ptr[buf.position + buf.offset]), len);
+ buf.count = result;
+
+ if (result == -1)
+ {
+ if (errno == EAGAIN) /* Non-blocking */
+ result = 0;
+ else
+ {
+ JCL_release_buffer(env, &buf, bbuf, JNI_ABORT);
+ JCL_ThrowException(env, IO_EXCEPTION, strerror(errno));
+ return -1;
+ }
+ }
+
+ JCL_release_buffer(env, &buf, bbuf, JNI_ABORT);
+
+ return result;
+}
+
+
+/*
+ * Implementation of a scattering read. Will use the appropriate
+ * vector based read call (currently readv on Linux).
+ *
+ * This has a limit to the number of buffers that will be read. It
+ * will not make muliple readv calls. This is to ensure that operations
+ * are atomic. Currently it is limited to 16 buffers. This is for
+ * compatibiliy with Sun.
+ */
+JNIEXPORT jlong JNICALL
+Java_gnu_java_nio_VMChannel_readScattering (JNIEnv *env,
+ jobject o __attribute__ ((__unused__)),
+ jint fd,
+ jobjectArray bbufs,
+ jint offset,
+ jint length)
+{
+ jint i;
+/* jboolean is_error = JNI_FALSE; */
+/* char *error_msg; */
+ struct iovec buffers[JCL_IOV_MAX];
+ struct JCL_buffer bi_list[JCL_IOV_MAX];
+ ssize_t result;
+ jint vec_len = length < JCL_IOV_MAX ? length : JCL_IOV_MAX;
+ jlong bytes_read = 0;
+
+ /* Build the vector of buffers to read into */
+ for (i = 0; i < vec_len; i++)
+ {
+ struct JCL_buffer* buf;
+ jobject bbuf;
+
+ buf = &bi_list[i];
+ bbuf = (*env)->GetObjectArrayElement(env, bbufs, offset + i);
+
+ JCL_init_buffer(env, buf, bbuf);
+
+ buffers[i].iov_base = &(buf->ptr[buf->position + buf->offset]);
+ buffers[i].iov_len = buf->limit - buf->position;
+ (*env)->DeleteLocalRef(env, bbuf);
+ }
+
+ /* Work the scattering magic */
+ result = readv(fd, buffers, vec_len);
+ bytes_read = (jlong) result;
+
+ /* Handle the response */
+ if (result < 0)
+ {
+ if (errno == EAGAIN) /* Non blocking */
+ result = 0;
+ else if (errno == EBADF) /* Bad fd */
+ {
+ JCL_cleanup_buffers(env, bi_list, vec_len, bbufs, offset, bytes_read);
+ JCL_ThrowException (env, NON_READABLE_CHANNEL_EXCEPTION,
+ strerror(errno));
+ return -1;
+ }
+ else
+ {
+ JCL_cleanup_buffers(env, bi_list, vec_len, bbufs, offset, bytes_read);
+ JCL_ThrowException (env, IO_EXCEPTION, strerror(errno));
+ return -1;
+ }
+ bytes_read = 0;
+ }
+ else if (result == 0) /* EOF */
+ {
+ result = -1;
+ }
+
+ JCL_cleanup_buffers(env, bi_list, vec_len, bbufs, offset, bytes_read);
+
+ return (jlong) result;
+}
+
+/*
+ * Implementation of a gathering write. Will use the appropriate
+ * vector based read call (currently readv on Linux).
+ *
+ * This has a limit to the number of buffers that will be read. It
+ * will not make muliple readv calls. This is to ensure that operations
+ * are atomic. Currently it is limited to 16 buffers. This is for
+ * compatibiliy with Sun.
+ */
+JNIEXPORT jlong JNICALL
+Java_gnu_java_nio_VMChannel_writeGathering (JNIEnv *env,
+ jobject o __attribute__ ((__unused__)),
+ jint fd,
+ jobjectArray bbufs,
+ jint offset,
+ jint length)
+{
+ int i;
+/* jboolean is_error = JNI_FALSE; */
+/* char *error_msg; */
+ struct iovec buffers[JCL_IOV_MAX];
+ struct JCL_buffer bi_list[JCL_IOV_MAX];
+ ssize_t result;
+ jint vec_len = length < JCL_IOV_MAX ? length : JCL_IOV_MAX;
+ jlong bytes_written;
+
+
+ /* Build the vector of buffers to read into */
+ for (i = 0; i < vec_len; i++)
+ {
+ struct JCL_buffer* buf;
+ jobject bbuf;
+
+ buf = &bi_list[i];
+ bbuf = (*env)->GetObjectArrayElement(env, bbufs, offset + i);
+
+ JCL_init_buffer(env, buf, bbuf);
+
+ buffers[i].iov_base = &(buf->ptr[buf->position + buf->offset]);
+ buffers[i].iov_len = buf->limit - buf->position;
+ (*env)->DeleteLocalRef(env, bbuf);
+ }
+
+ /* Work the gathering magic */
+ result = writev(fd, buffers, vec_len);
+ bytes_written = (jlong) result;
+
+ if (result < 0)
+ {
+ bytes_written = 0;
+ if (errno == EAGAIN) /* Non blocking */
+ result = 0;
+ else if (errno == EBADF) /* Bad fd */
+ {
+ JCL_cleanup_buffers(env, bi_list, vec_len, bbufs, offset,
+ bytes_written);
+ JCL_ThrowException (env, NON_WRITABLE_CHANNEL_EXCEPTION,
+ strerror(errno));
+ return -1;
+ }
+ else
+ {
+ JCL_cleanup_buffers(env, bi_list, vec_len, bbufs, offset,
+ bytes_written);
+ JCL_ThrowException (env, IO_EXCEPTION, strerror(errno));
+ return -1;
+ }
+ }
+ else if (result == 0) /* EOF?? Does this happen on a write */
+ result = -1;
+
+ JCL_cleanup_buffers(env, bi_list, vec_len, bbufs, offset, bytes_written);
+ return (jlong) result;
+}
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/native/jni/midi-dssi/dssi_data.h b/native/jni/midi-dssi/dssi_data.h
index 07df950db..f8243f29b 100644
--- a/native/jni/midi-dssi/dssi_data.h
+++ b/native/jni/midi-dssi/dssi_data.h
@@ -1,5 +1,5 @@
/* dssi_data.h - DSSI data
- Copyright (C) 2005 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -53,11 +53,6 @@ exception statement from your version. */
1/40th of a second). */
#define EVENT_BUFFER_SIZE 1024
-/* Helper macros for going between pointers and jlongs. */
-#define JLONG_TO_PTR(T,P) ((T *)(long)P)
-#define PTR_TO_JLONG(P) ((jlong)(long)P)
-
-
/* Every DSSI Synthesizer has one of these associated with it. The
Java class sees it as a "long" handle. */
diff --git a/native/jni/native-lib/cpproc.h b/native/jni/native-lib/cpproc.h
index cfe82ab08..6efd10712 100644
--- a/native/jni/native-lib/cpproc.h
+++ b/native/jni/native-lib/cpproc.h
@@ -42,7 +42,7 @@ exception statement from your version. */
#define CPIO_EXEC_STDIN 0
#define CPIO_EXEC_STDOUT 1
#define CPIO_EXEC_STDERR 2
-#define CPIO_EXEC_NUMPIPES 3
+#define CPIO_EXEC_NUM_PIPES 3
JNIEXPORT int cpproc_forkAndExec (char * const *commandLine, char * const * newEnviron, int *fds, pid_t *pid, const char *wd);
JNIEXPORT int cpproc_waitpid (pid_t pid, int *status, pid_t *outpid, int options);
diff --git a/native/jni/qt-peer/eventmethods.h b/native/jni/qt-peer/eventmethods.h
index ea5d45a5c..ae56da8e7 100644
--- a/native/jni/qt-peer/eventmethods.h
+++ b/native/jni/qt-peer/eventmethods.h
@@ -1,5 +1,5 @@
/* eventmethods.cpp --
- Copyright (C) 2005 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -62,7 +62,7 @@ private:
env->DeleteGlobalRef(componentCls);
}
- void callVoidMethod(char *methodName)
+ void callVoidMethod(const char *methodName)
{
JNIEnv *env;
vm->GetEnv((void **)&env, JNI_VERSION_1_1);
@@ -72,7 +72,7 @@ private:
env->CallVoidMethod( target, fireEventID );
}
- void callMouseMethod(char *methodName,
+ void callMouseMethod(const char *methodName,
int modifiers, int x, int y, int clickCount)
{
JNIEnv *env;
diff --git a/native/jni/qt-peer/qtmenupeer.cpp b/native/jni/qt-peer/qtmenupeer.cpp
index 1ac17145c..6f35c89b9 100644
--- a/native/jni/qt-peer/qtmenupeer.cpp
+++ b/native/jni/qt-peer/qtmenupeer.cpp
@@ -44,9 +44,11 @@ exception statement from your version. */
#include "slotcallbacks.h"
#include "componentevent.h"
-#define ADDMENU 0
-#define ADDITEM 1
-#define ADDSEPA 2
+typedef enum ActionType {
+ ActionMenu,
+ ActionItem,
+ ActionSeparator
+} ActionType;
// Sets the title, but also tear-off.
class MenuTitleEvent : public AWTEvent {
@@ -81,18 +83,18 @@ class MenuAction : public AWTEvent {
private:
QMenu *menu;
QAction *action;
- int isMenu; // 0 to add a menu, 1 to add an item, 2 to add a seperator
+ ActionType actionType; // type of action to add
JavaVM *vm;
jobject menuPeer;
jobject itemPeer;
public:
MenuAction(JNIEnv *env, jobject mp, jobject ip, QMenu *m, QAction *a,
- bool ismenu) : AWTEvent()
+ ActionType actionType) : AWTEvent()
{
menu = m;
action = a;
- isMenu = ismenu;
+ this->actionType = actionType;
env->GetJavaVM( &vm );
menuPeer = env->NewGlobalRef( mp );
if( ip != NULL )
@@ -104,35 +106,22 @@ public:
void runEvent()
{
JNIEnv *env;
- QAction *newAction; // adding an action creates a new duplicate.
vm->GetEnv((void **)&env, JNI_VERSION_1_1);
-
- switch(isMenu)
- {
- case ADDMENU:
- newAction = menu->addMenu( (QMenu *)action );
- break;
- case ADDITEM:
- newAction = menu->addAction(action->text());
- newAction->setSeparator(action->isSeparator());
- newAction->setCheckable(action->isCheckable());
- // delete action;
- break;
- case ADDSEPA:
- newAction = menu->addSeparator();
- break;
- }
+ if (actionType == ActionMenu)
+ menu->addMenu ((QMenu *) action);
+ else
+ menu->addAction (action);
jclass menuCls = env->GetObjectClass( menuPeer );
jmethodID mid = env->GetMethodID(menuCls, "add", "(J)V");
env->DeleteLocalRef(menuCls);
- env->CallVoidMethod( menuPeer, mid, (jlong)newAction );
+ env->CallVoidMethod( menuPeer, mid, (jlong)action );
env->DeleteGlobalRef( menuPeer );
if( itemPeer != NULL )
{
- setNativeObject( env, itemPeer, newAction );
- connectAction(newAction, env, itemPeer);
+ setNativeObject( env, itemPeer, action );
+ connectAction(action, env, itemPeer);
env->DeleteGlobalRef( itemPeer );
}
}
@@ -190,7 +179,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtMenuPeer_insertSeperator
QMenu *menu = (QMenu *)getNativeObject( env, obj );
assert( menu );
mainThread->postEventToMain( new MenuAction( env, obj, NULL,
- menu, NULL, ADDSEPA ) );
+ menu, NULL, ActionSeparator ) );
}
/*
@@ -205,7 +194,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtMenuPeer_insertItem
QAction *action = (QAction *)getNativeObject( env, item );
assert( action );
- mainThread->postEventToMain( new MenuAction( env, obj, item, menu, action, ADDITEM ));
+ mainThread->postEventToMain( new MenuAction( env, obj, item, menu, action, ActionItem ));
}
/*
@@ -220,7 +209,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtMenuPeer_insertMenu
QMenu *insMenu = (QMenu *)getNativeObject(env, menu);
assert( insMenu );
- mainThread->postEventToMain( new MenuAction( env, obj, menu, thisMenu, (QAction *)insMenu, ADDMENU ) );
+ mainThread->postEventToMain( new MenuAction( env, obj, menu, thisMenu, (QAction *)insMenu, ActionMenu ) );
}
/*
diff --git a/native/plugin/.cvsignore b/native/plugin/.cvsignore
new file mode 100644
index 000000000..17cbfe80b
--- /dev/null
+++ b/native/plugin/.cvsignore
@@ -0,0 +1,6 @@
+Makefile.in
+.deps
+.libs
+libgcjwebplugin_la-gcjwebplugin.lo
+libgcjwebplugin.la
+Makefile
diff --git a/native/plugin/Makefile.am b/native/plugin/Makefile.am
new file mode 100644
index 000000000..19c7618d8
--- /dev/null
+++ b/native/plugin/Makefile.am
@@ -0,0 +1,19 @@
+lib_LTLIBRARIES = libgcjwebplugin.la
+
+libgcjwebplugin_la_SOURCES = gcjwebplugin.cc
+
+libgcjwebplugin_la_CXXFLAGS = \
+ -Wall -DAPPLETVIEWER_EXECUTABLE="\"$(bindir)/appletviewer\"" \
+ -DPLUGIN_DATA_DIRECTORY="\"$(PLUGIN_DIR)/gcjwebplugin-data\"" \
+ $(MOZILLA_CFLAGS) $(GLIB_CFLAGS) $(GTK_CFLAGS)
+
+libgcjwebplugin_la_LDFLAGS = -avoid-version \
+ $(GLIB_LIBS) $(GTK_LIBS) \
+ -lstdc++
+
+install-plugin: $(lib_LTLIBRARIES)
+ $(INSTALL) -d -m0755 $(DESTDIR)$(PLUGIN_DIR)
+ $(INSTALL) .libs/libgcjwebplugin.so $(DESTDIR)$(PLUGIN_DIR)
+
+uninstall-plugin:
+ rm -f $(DESTDIR)$(PLUGIN_DIR)/libgcjwebplugin.so
diff --git a/native/plugin/gcjwebplugin.cc b/native/plugin/gcjwebplugin.cc
new file mode 100644
index 000000000..72e5115a8
--- /dev/null
+++ b/native/plugin/gcjwebplugin.cc
@@ -0,0 +1,1745 @@
+/* gcjwebplugin.cc -- web browser plugin to execute Java applets
+ Copyright (C) 2003, 2004, 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. */
+
+// System includes.
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+// Netscape plugin API includes.
+#include <npapi.h>
+#include <npupp.h>
+
+// GLib includes.
+#include <glib.h>
+#include <glib/gstdio.h>
+
+// GTK includes.
+#include <gtk/gtk.h>
+
+// gcjwebplugin includes.
+#include "config.h"
+
+// Documentbase retrieval includes.
+#include <nsIPluginInstance.h>
+#include <nsIPluginInstancePeer.h>
+#include <nsIPluginTagInfo2.h>
+
+// Debugging macros.
+#define PLUGIN_DEBUG(message) \
+ g_print ("GCJ PLUGIN: thread %p: %s\n", g_thread_self (), message)
+
+#define PLUGIN_DEBUG_TWO(first, second) \
+ g_print ("GCJ PLUGIN: thread %p: %s %s\n", g_thread_self (), \
+ first, second)
+
+// Error reporting macros.
+#define PLUGIN_ERROR(message) \
+ g_printerr ("%s:%d: thread %p: Error: %s\n", __FILE__, __LINE__, \
+ g_thread_self (), message)
+
+#define PLUGIN_ERROR_TWO(first, second) \
+ g_printerr ("%s:%d: thread %p: Error: %s: %s\n", __FILE__, __LINE__, \
+ g_thread_self (), first, second)
+
+// Plugin information passed to about:plugins.
+#define PLUGIN_NAME "GCJ Web Browser Plugin"
+#define PLUGIN_DESC "The " PLUGIN_NAME " executes Java applets."
+#define PLUGIN_MIME_DESC \
+ "application/x-java-vm:class,jar:GCJ;" \
+ "application/x-java-applet:class,jar:GCJ;" \
+ "application/x-java-applet;version=1.1:class,jar:GCJ;" \
+ "application/x-java-applet;version=1.1.1:class,jar:GCJ;" \
+ "application/x-java-applet;version=1.1.2:class,jar:GCJ;" \
+ "application/x-java-applet;version=1.1.3:class,jar:GCJ;" \
+ "application/x-java-applet;version=1.2:class,jar:GCJ;" \
+ "application/x-java-applet;version=1.2.1:class,jar:GCJ;" \
+ "application/x-java-applet;version=1.2.2:class,jar:GCJ;" \
+ "application/x-java-applet;version=1.3:class,jar:GCJ;" \
+ "application/x-java-applet;version=1.3.1:class,jar:GCJ;" \
+ "application/x-java-applet;version=1.4:class,jar:GCJ;" \
+ "application/x-java-applet;version=1.4.1:class,jar:GCJ;" \
+ "application/x-java-applet;version=1.4.2:class,jar:GCJ;" \
+ "application/x-java-applet;jpi-version=1.4.2_01:class,jar:GCJ;" \
+ "application/x-java-bean:class,jar:GCJ;" \
+ "application/x-java-bean;version=1.1:class,jar:GCJ;" \
+ "application/x-java-bean;version=1.1.1:class,jar:GCJ;" \
+ "application/x-java-bean;version=1.1.2:class,jar:GCJ;" \
+ "application/x-java-bean;version=1.1.3:class,jar:GCJ;" \
+ "application/x-java-bean;version=1.2:class,jar:GCJ;" \
+ "application/x-java-bean;version=1.2.1:class,jar:GCJ;" \
+ "application/x-java-bean;version=1.2.2:class,jar:GCJ;" \
+ "application/x-java-bean;version=1.3:class,jar:GCJ;" \
+ "application/x-java-bean;version=1.3.1:class,jar:GCJ;" \
+ "application/x-java-bean;version=1.4:class,jar:GCJ;" \
+ "application/x-java-bean;version=1.4.1:class,jar:GCJ;" \
+ "application/x-java-bean;version=1.4.2:class,jar:GCJ;" \
+ "application/x-java-bean;jpi-version=1.4.2_01:class,jar:GCJ;"
+#define PLUGIN_URL NS_INLINE_PLUGIN_CONTRACTID_PREFIX NS_JVM_MIME_TYPE
+#define PLUGIN_MIME_TYPE "application/x-java-vm"
+#define PLUGIN_FILE_EXTS "class,jar,zip"
+#define PLUGIN_MIME_COUNT 1
+
+// Security dialog messages.
+#define RESPONSE_TRUST_APPLET "Trust Applet"
+#define RESPONSE_TRUST_APPLET_ADD_TO_LIST "Trust Applet and Add to Whitelist"
+#define WHITELIST_FILENAME PLUGIN_DATA_DIRECTORY "/whitelist.txt"
+#define SECURITY_WARNING \
+ "%s wants to load an applet.\n" \
+ "GNU Classpath's security implementation is not complete.\n" \
+ "HOSTILE APPLETS WILL STEAL AND/OR DESTROY YOUR DATA!\n"
+#define SECURITY_DESCRIPTION \
+ "If you do not know or trust the source of this applet, click" \
+ " \"Cancel\".\n" \
+ "Click \"Trust Applet\" to load and run this applet now.\n" \
+ "Click \"Trust Applet and Add To Whitelist\" to always load" \
+ " and run this applet from now on, without asking.\n" \
+ "The whitelist is a list of the URLs from which you trust" \
+ " applets.\n" \
+ "Your whitelist file is \"" WHITELIST_FILENAME "\"."
+#define FAILURE_MESSAGE \
+ "This page wants to load an applet.\n" \
+ "There is no appletviewer installed in \"" APPLETVIEWER_EXECUTABLE "\"." \
+
+// Documentbase retrieval required definition.
+static NS_DEFINE_IID (kIPluginTagInfo2IID, NS_IPLUGINTAGINFO2_IID);
+
+// Browser function table.
+static NPNetscapeFuncs browserFunctions;
+
+// Keeps track of initialization. NP_INITIALIZE should only be
+// called once.
+bool initialized = false;
+
+// GCJPluginData stores all the data associated with a single plugin
+// instance. A separate plugin instance is created for each <APPLET>
+// tag. For now, each plugin instance spawns its own applet viewer
+// process but this may need to change if we find pages containing
+// multiple applets that expect to be running in the same VM.
+struct GCJPluginData
+{
+ // A unique identifier for this plugin window.
+ gchar* instance_string;
+ // Applet viewer input pipe name.
+ gchar* in_pipe_name;
+ // Applet viewer input channel.
+ GIOChannel* in_from_appletviewer;
+ // Applet viewer input watch source.
+ gint in_watch_source;
+ // Applet viewer output pipe name.
+ gchar* out_pipe_name;
+ // Applet viewer output channel.
+ GIOChannel* out_to_appletviewer;
+ // Applet viewer output watch source.
+ gint out_watch_source;
+ // Mutex to protect appletviewer_alive.
+ GMutex* appletviewer_mutex;
+ // Back-pointer to the plugin instance to which this data belongs.
+ // This should not be freed but instead simply set to NULL.
+ NPP owner;
+ // FALSE if the applet viewer process has died. All code
+ // communicating with the applet viewer should check this flag
+ // before attempting to read from/write to the applet viewer pipes.
+ gboolean appletviewer_alive;
+ // The address of the plugin window. This should not be freed but
+ // instead simply set to NULL.
+ gpointer window_handle;
+ // The last plugin window width sent to us by the browser.
+ guint32 window_width;
+ // The last plugin window height sent to us by the browser.
+ guint32 window_height;
+};
+
+// Documentbase retrieval type-punning union.
+typedef union
+{
+ void** void_field;
+ nsIPluginTagInfo2** info_field;
+} info_union;
+
+// Static instance helper functions.
+// Have the browser allocate a new GCJPluginData structure.
+static void plugin_data_new (GCJPluginData** data);
+// Documentbase retrieval.
+static gchar* plugin_get_documentbase (NPP instance);
+// plugin failure handling.
+static bool plugin_failed ();
+// Whitelist handling.
+static bool plugin_user_trusts_documentbase (char* documentbase);
+static bool plugin_ask_user_about_documentbase (char* documentbase);
+static void plugin_add_documentbase_to_whitelist (char* documentbase);
+// Callback used to monitor input pipe status.
+static gboolean plugin_in_pipe_callback (GIOChannel* source,
+ GIOCondition condition,
+ gpointer plugin_data);
+// Callback used to monitor output pipe status.
+static gboolean plugin_out_pipe_callback (GIOChannel* source,
+ GIOCondition condition,
+ gpointer plugin_data);
+static NPError plugin_start_appletviewer (GCJPluginData* data);
+static gchar* plugin_create_applet_tag (int16 argc, char* argn[],
+ char* argv[]);
+static void plugin_send_message_to_appletviewer (GCJPluginData* data,
+ gchar const* message);
+static void plugin_stop_appletviewer (GCJPluginData* data);
+// Uninitialize GCJPluginData structure and delete pipes.
+static void plugin_data_destroy (GCJPluginData** data);
+
+// Global instance counter.
+// Mutex to protect plugin_instance_counter.
+static GMutex* plugin_instance_mutex = NULL;
+// A counter used to create uniquely named pipes.
+static gulong plugin_instance_counter = 0;
+// The user's documentbase whitelist.
+static GIOChannel* whitelist_file = NULL;
+// A global variable for reporting GLib errors. This must be free'd
+// and set to NULL after each use.
+static GError* channel_error = NULL;
+
+// Functions prefixed by GCJ_ are instance functions. They are called
+// by the browser and operate on instances of GCJPluginData.
+// Functions prefixed by plugin_ are static helper functions.
+// Functions prefixed by NP_ are factory functions. They are called
+// by the browser and provide functionality needed to create plugin
+// instances.
+
+// INSTANCE FUNCTIONS
+
+// Creates a new gcjwebplugin instance. This function creates a
+// GCJPluginData* and stores it in instance->pdata. The following
+// GCJPluginData fiels are initialized: instance_string, in_pipe_name,
+// in_from_appletviewer, in_watch_source, out_pipe_name,
+// out_to_appletviewer, out_watch_source, appletviewer_mutex, owner,
+// appletviewer_alive. In addition two pipe files are created. All
+// of those fields must be properly destroyed, and the pipes deleted,
+// by GCJ_Destroy. If an error occurs during initialization then this
+// function will free anything that's been allocated so far, set
+// instance->pdata to NULL and return an error code.
+NPError
+GCJ_New (NPMIMEType pluginType, NPP instance, uint16 mode,
+ int16 argc, char* argn[], char* argv[],
+ NPSavedData* saved)
+{
+ PLUGIN_DEBUG ("GCJ_New");
+
+ NPError np_error = NPERR_NO_ERROR;
+ GCJPluginData* data = NULL;
+
+ gchar* documentbase = NULL;
+ gchar* read_message = NULL;
+ gchar* applet_tag = NULL;
+ gchar* tag_message = NULL;
+
+ if (!instance)
+ {
+ PLUGIN_ERROR ("Browser-provided instance pointer is NULL.");
+ np_error = NPERR_INVALID_INSTANCE_ERROR;
+ goto cleanup_done;
+ }
+
+ // Initialize threads (needed for mutexes).
+ if (!g_thread_supported ())
+ g_thread_init (NULL);
+
+ // data
+ plugin_data_new (&data);
+ if (data == NULL)
+ {
+ PLUGIN_ERROR ("Failed to allocate plugin data.");
+ np_error = NPERR_OUT_OF_MEMORY_ERROR;
+ goto cleanup_done;
+ }
+
+ // Initialize data->instance_string.
+ //
+ // instance_string should be unique for this process so we use a
+ // combination of getpid and plugin_instance_counter.
+ //
+ // Critical region. Reference and increment plugin_instance_counter
+ // global.
+ g_mutex_lock (plugin_instance_mutex);
+
+ // data->instance_string
+ data->instance_string = g_strdup_printf ("instance-%d-%ld",
+ getpid (),
+ plugin_instance_counter++);
+
+ g_mutex_unlock (plugin_instance_mutex);
+
+ // data->appletviewer_mutex
+ data->appletviewer_mutex = g_mutex_new ();
+
+ // Documentbase retrieval.
+ documentbase = plugin_get_documentbase (instance);
+ if (!documentbase)
+ {
+ PLUGIN_ERROR ("Documentbase retrieval failed."
+ " Browser not Mozilla-based?");
+ goto cleanup_appletviewer_mutex;
+ }
+
+ if (!plugin_user_trusts_documentbase (documentbase))
+ {
+ PLUGIN_ERROR ("User does not trust applet.");
+ np_error = NPERR_GENERIC_ERROR;
+ goto cleanup_appletviewer_mutex;
+ }
+
+ // Create appletviewer-to-plugin pipe which we refer to as the input
+ // pipe.
+
+ // data->in_pipe_name
+ data->in_pipe_name = g_strdup_printf (PLUGIN_DATA_DIRECTORY
+ "/gcj-%s-appletviewer-to-plugin",
+ data->instance_string);
+ if (!data->in_pipe_name)
+ {
+ PLUGIN_ERROR ("Failed to create input pipe name.");
+ np_error = NPERR_OUT_OF_MEMORY_ERROR;
+ // If data->in_pipe_name is NULL then the g_free at
+ // cleanup_in_pipe_name will simply return.
+ goto cleanup_in_pipe_name;
+ }
+
+ if (mkfifo (data->in_pipe_name, 0700) == -1 && errno != EEXIST)
+ {
+ PLUGIN_ERROR_TWO ("Failed to create input pipe", strerror (errno));
+ np_error = NPERR_GENERIC_ERROR;
+ goto cleanup_in_pipe_name;
+ }
+
+ // Create plugin-to-appletviewer pipe which we refer to as the
+ // output pipe.
+
+ // data->out_pipe_name
+ data->out_pipe_name = g_strdup_printf (PLUGIN_DATA_DIRECTORY
+ "/gcj-%s-plugin-to-appletviewer",
+ data->instance_string);
+
+ if (!data->out_pipe_name)
+ {
+ PLUGIN_ERROR ("Failed to create output pipe name.");
+ np_error = NPERR_OUT_OF_MEMORY_ERROR;
+ goto cleanup_out_pipe_name;
+ }
+
+ if (mkfifo (data->out_pipe_name, 0700) == -1 && errno != EEXIST)
+ {
+ PLUGIN_ERROR_TWO ("Failed to create output pipe", strerror (errno));
+ np_error = NPERR_GENERIC_ERROR;
+ goto cleanup_out_pipe_name;
+ }
+
+ // Start a separate appletviewer process for each applet, even if
+ // there are multiple applets in the same page. We may need to
+ // change this behaviour if we find pages with multiple applets that
+ // rely on being run in the same VM.
+
+ // Critical region. Hold appletviewer_mutex while we start the
+ // appletviewer, create the IO channels and install the channel
+ // watch callbacks.
+ g_mutex_lock (data->appletviewer_mutex);
+
+ np_error = plugin_start_appletviewer (data);
+
+ // If the appletviewer is not installed, then a dialog box will
+ // show up and the plugin will be killed.
+ if (np_error != NPERR_NO_ERROR)
+ {
+ if (plugin_failed ())
+ goto cleanup_applet_failure;
+ }
+
+ // Create plugin-to-appletviewer channel. The default encoding for
+ // the file is UTF-8.
+ // data->out_to_appletviewer
+ data->out_to_appletviewer = g_io_channel_new_file (data->out_pipe_name,
+ "w", &channel_error);
+ if (!data->out_to_appletviewer)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to create output channel",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to create output channel");
+
+ np_error = NPERR_GENERIC_ERROR;
+ goto cleanup_out_to_appletviewer;
+ }
+
+ // Watch for hangup and error signals on the output pipe.
+ data->out_watch_source =
+ g_io_add_watch (data->out_to_appletviewer,
+ (GIOCondition) (G_IO_ERR | G_IO_HUP),
+ plugin_out_pipe_callback, (gpointer) data);
+
+ // Create appletviewer-to-plugin channel. The default encoding for
+ // the file is UTF-8.
+ // data->in_from_appletviewer
+ data->in_from_appletviewer = g_io_channel_new_file (data->in_pipe_name,
+ "r", &channel_error);
+ if (!data->in_from_appletviewer)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to create input channel",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to create input channel");
+
+ np_error = NPERR_GENERIC_ERROR;
+ goto cleanup_in_from_appletviewer;
+ }
+
+ // Watch for hangup and error signals on the input pipe.
+ data->in_watch_source =
+ g_io_add_watch (data->in_from_appletviewer,
+ (GIOCondition) (G_IO_IN | G_IO_ERR | G_IO_HUP),
+ plugin_in_pipe_callback, (gpointer) data);
+
+ // Wait until we receive confirmation that the appletviewer has
+ // started.
+ if (g_io_channel_read_line (data->in_from_appletviewer,
+ &read_message, NULL, NULL,
+ &channel_error)
+ != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Receiving confirmation from appletviewer failed",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Receiving confirmation from appletviewer failed");
+
+ np_error = NPERR_GENERIC_ERROR;
+ goto cleanup_in_watch_source;
+ }
+
+ PLUGIN_DEBUG ("GCJ_New: got confirmation that appletviewer is running.");
+ data->appletviewer_alive = TRUE;
+
+ // Send applet tag message to appletviewer.
+ applet_tag = plugin_create_applet_tag (argc, argn, argv);
+ tag_message = g_strconcat ("tag ", documentbase, " ", applet_tag, NULL);
+
+ plugin_send_message_to_appletviewer (data, data->instance_string);
+ plugin_send_message_to_appletviewer (data, tag_message);
+
+ g_mutex_unlock (data->appletviewer_mutex);
+
+ // If initialization succeeded entirely then we store the plugin
+ // data in the instance structure and return. Otherwise we free the
+ // data we've allocated so far and set instance->pdata to NULL.
+
+ // Set back-pointer to owner instance.
+ data->owner = instance;
+ instance->pdata = data;
+ goto cleanup_done;
+
+ // An error occurred while initializing the plugin data or spawning
+ // the appletviewer so we free the data we've already allocated.
+
+ cleanup_in_watch_source:
+ // Removing a source is harmless if it fails since it just means the
+ // source has already been removed.
+ g_source_remove (data->in_watch_source);
+ data->in_watch_source = 0;
+
+ cleanup_in_from_appletviewer:
+ if (data->in_from_appletviewer)
+ g_io_channel_unref (data->in_from_appletviewer);
+ data->in_from_appletviewer = NULL;
+
+ // cleanup_out_watch_source:
+ g_source_remove (data->out_watch_source);
+ data->out_watch_source = 0;
+
+ cleanup_out_to_appletviewer:
+ if (data->out_to_appletviewer)
+ g_io_channel_unref (data->out_to_appletviewer);
+ data->out_to_appletviewer = NULL;
+
+ // cleanup_out_pipe:
+ // Delete output pipe.
+ unlink (data->out_pipe_name);
+
+ cleanup_applet_failure:
+ cleanup_out_pipe_name:
+ g_free (data->out_pipe_name);
+ data->out_pipe_name = NULL;
+
+ // cleanup_in_pipe:
+ // Delete input pipe.
+ unlink (data->in_pipe_name);
+
+ cleanup_in_pipe_name:
+ g_free (data->in_pipe_name);
+ data->in_pipe_name = NULL;
+
+ cleanup_appletviewer_mutex:
+ g_free (data->appletviewer_mutex);
+ data->appletviewer_mutex = NULL;
+
+ // cleanup_instance_string:
+ g_free (data->instance_string);
+ data->instance_string = NULL;
+
+ // cleanup_data:
+ // Eliminate back-pointer to plugin instance.
+ data->owner = NULL;
+ (*browserFunctions.memfree) (data);
+ data = NULL;
+
+ // Initialization failed so return a NULL pointer for the browser
+ // data.
+ instance->pdata = NULL;
+
+ cleanup_done:
+ g_free (tag_message);
+ tag_message = NULL;
+ g_free (applet_tag);
+ applet_tag = NULL;
+ g_free (read_message);
+ read_message = NULL;
+ g_free (documentbase);
+ documentbase = NULL;
+
+ PLUGIN_DEBUG ("GCJ_New return");
+
+ return np_error;
+}
+
+NPError
+GCJ_GetValue (NPP instance, NPPVariable variable, void* value)
+{
+ PLUGIN_DEBUG ("GCJ_GetValue");
+
+ NPError np_error = NPERR_NO_ERROR;
+
+ switch (variable)
+ {
+ // This plugin needs XEmbed support.
+ case NPPVpluginNeedsXEmbed:
+ {
+ PLUGIN_DEBUG ("GCJ_GetValue: returning TRUE for NeedsXEmbed.");
+ PRBool* bool_value = (PRBool*) value;
+ *bool_value = PR_TRUE;
+ }
+ break;
+
+ default:
+ PLUGIN_ERROR ("Unknown plugin value requested.");
+ np_error = NPERR_GENERIC_ERROR;
+ break;
+ }
+
+ PLUGIN_DEBUG ("GCJ_GetValue return");
+
+ return np_error;
+}
+
+NPError
+GCJ_Destroy (NPP instance, NPSavedData** save)
+{
+ PLUGIN_DEBUG ("GCJ_Destroy");
+
+ GCJPluginData* data = (GCJPluginData*) instance->pdata;
+
+ if (data)
+ {
+ // Critical region. Stop the appletviewer.
+ g_mutex_lock (data->appletviewer_mutex);
+
+ // Tell the appletviewer to destroy its embedded plugin window.
+ plugin_send_message_to_appletviewer (data, "destroy");
+ // Shut down the appletviewer.
+ plugin_stop_appletviewer (data);
+
+ g_mutex_unlock (data->appletviewer_mutex);
+
+ // Free plugin data.
+ plugin_data_destroy (&data);
+ }
+
+ PLUGIN_DEBUG ("GCJ_Destroy return");
+
+ return NPERR_NO_ERROR;
+}
+
+NPError
+GCJ_SetWindow (NPP instance, NPWindow* window)
+{
+ PLUGIN_DEBUG ("GCJ_SetWindow");
+
+ if (instance == NULL)
+ {
+ PLUGIN_ERROR ("Invalid instance.");
+
+ return NPERR_INVALID_INSTANCE_ERROR;
+ }
+
+ GCJPluginData* data = (GCJPluginData*) instance->pdata;
+
+ // Simply return if we receive a NULL window.
+ if ((window == NULL) || (window->window == NULL))
+ {
+ PLUGIN_DEBUG ("GCJ_SetWindow: got NULL window.");
+
+ return NPERR_NO_ERROR;
+ }
+
+ if (data->window_handle)
+ {
+ // The window already exists.
+ if (data->window_handle == window->window)
+ {
+ // The parent window is the same as in previous calls.
+ PLUGIN_DEBUG ("GCJ_SetWindow: window already exists.");
+
+ // Critical region. Read data->appletviewer_mutex and send
+ // a message to the appletviewer.
+ g_mutex_lock (data->appletviewer_mutex);
+
+ if (data->appletviewer_alive)
+ {
+ // The window is the same as it was for the last
+ // SetWindow call.
+ if (window->width != data->window_width)
+ {
+ PLUGIN_DEBUG ("GCJ_SetWindow: window width changed.");
+ // The width of the plugin window has changed.
+
+ // Send the new width to the appletviewer.
+ plugin_send_message_to_appletviewer (data,
+ data->instance_string);
+ gchar* width_message = g_strdup_printf ("width %d",
+ window->width);
+ plugin_send_message_to_appletviewer (data, width_message);
+ g_free (width_message);
+ width_message = NULL;
+
+ // Store the new width.
+ data->window_width = window->width;
+ }
+
+ if (window->height != data->window_height)
+ {
+ PLUGIN_DEBUG ("GCJ_SetWindow: window height changed.");
+ // The height of the plugin window has changed.
+
+ // Send the new height to the appletviewer.
+ plugin_send_message_to_appletviewer (data,
+ data->instance_string);
+ gchar* height_message = g_strdup_printf ("height %d",
+ window->height);
+ plugin_send_message_to_appletviewer (data, height_message);
+ g_free (height_message);
+ height_message = NULL;
+
+ // Store the new height.
+ data->window_height = window->height;
+ }
+ }
+ else
+ {
+ // The appletviewer is not running.
+ PLUGIN_DEBUG ("GCJ_SetWindow: appletviewer is not running.");
+ }
+
+ g_mutex_unlock (data->appletviewer_mutex);
+ }
+ else
+ {
+ // The parent window has changed. This branch does run but
+ // doing nothing in response seems to be sufficient.
+ PLUGIN_DEBUG ("GCJ_SetWindow: parent window changed.");
+ }
+ }
+ else
+ {
+ PLUGIN_DEBUG ("GCJ_SetWindow: setting window.");
+
+ // Critical region. Send messages to appletviewer.
+ g_mutex_lock (data->appletviewer_mutex);
+
+ plugin_send_message_to_appletviewer (data, data->instance_string);
+ gchar *window_message = g_strdup_printf ("handle %ld",
+ (gulong) window->window);
+ plugin_send_message_to_appletviewer (data, window_message);
+ g_free (window_message);
+ window_message = NULL;
+
+ g_mutex_unlock (data->appletviewer_mutex);
+
+ // Store the window handle.
+ data->window_handle = window->window;
+ }
+
+ PLUGIN_DEBUG ("GCJ_SetWindow return");
+
+ return NPERR_NO_ERROR;
+}
+
+NPError
+GCJ_NewStream (NPP instance, NPMIMEType type, NPStream* stream,
+ NPBool seekable, uint16* stype)
+{
+ PLUGIN_DEBUG ("GCJ_NewStream");
+
+ PLUGIN_DEBUG ("GCJ_NewStream return");
+
+ return NPERR_NO_ERROR;
+}
+
+void
+GCJ_StreamAsFile (NPP instance, NPStream* stream, const char* filename)
+{
+ PLUGIN_DEBUG ("GCJ_StreamAsFile");
+
+ PLUGIN_DEBUG ("GCJ_StreamAsFile return");
+}
+
+NPError
+GCJ_DestroyStream (NPP instance, NPStream* stream, NPReason reason)
+{
+ PLUGIN_DEBUG ("GCJ_DestroyStream");
+
+ PLUGIN_DEBUG ("GCJ_DestroyStream return");
+
+ return NPERR_NO_ERROR;
+}
+
+int32
+GCJ_WriteReady (NPP instance, NPStream* stream)
+{
+ PLUGIN_DEBUG ("GCJ_WriteReady");
+
+ PLUGIN_DEBUG ("GCJ_WriteReady return");
+
+ return 0;
+}
+
+int32
+GCJ_Write (NPP instance, NPStream* stream, int32 offset, int32 len,
+ void* buffer)
+{
+ PLUGIN_DEBUG ("GCJ_Write");
+
+ PLUGIN_DEBUG ("GCJ_Write return");
+
+ return 0;
+}
+
+void
+GCJ_Print (NPP instance, NPPrint* platformPrint)
+{
+ PLUGIN_DEBUG ("GCJ_Print");
+
+ PLUGIN_DEBUG ("GCJ_Print return");
+}
+
+int16
+GCJ_HandleEvent (NPP instance, void* event)
+{
+ PLUGIN_DEBUG ("GCJ_HandleEvent");
+
+ PLUGIN_DEBUG ("GCJ_HandleEvent return");
+
+ return 0;
+}
+
+void
+GCJ_URLNotify (NPP instance, const char* url, NPReason reason,
+ void* notifyData)
+{
+ PLUGIN_DEBUG ("GCJ_URLNotify");
+
+ PLUGIN_DEBUG ("GCJ_URLNotify return");
+}
+
+jref
+GCJ_GetJavaClass (void)
+{
+ PLUGIN_DEBUG ("GCJ_GetJavaClass");
+
+ PLUGIN_DEBUG ("GCJ_GetJavaClass return");
+
+ return 0;
+}
+
+// HELPER FUNCTIONS
+
+static void
+plugin_data_new (GCJPluginData** data)
+{
+ PLUGIN_DEBUG ("plugin_data_new");
+
+ *data = (GCJPluginData*)
+ (*browserFunctions.memalloc) (sizeof (struct GCJPluginData));
+
+ // appletviewer_alive is false until the applet viewer is spawned.
+ if (*data)
+ memset (*data, 0, sizeof (struct GCJPluginData));
+
+ PLUGIN_DEBUG ("plugin_data_new return");
+}
+
+// Documentbase retrieval. This function gets the current document's
+// documentbase. This function relies on browser-private data so it
+// will only work when the plugin is loaded in a Mozilla-based
+// browser. We could not find a way to retrieve the documentbase
+// using the original Netscape plugin API so we use the XPCOM API
+// instead.
+static gchar*
+plugin_get_documentbase (NPP instance)
+{
+ PLUGIN_DEBUG ("plugin_get_documentbase");
+
+ nsIPluginInstance* xpcom_instance = NULL;
+ nsIPluginInstancePeer* peer = NULL;
+ nsresult result = 0;
+ nsIPluginTagInfo2* pluginTagInfo2 = NULL;
+ info_union u = { NULL };
+ char const* documentbase = NULL;
+ gchar* documentbase_copy = NULL;
+
+ xpcom_instance = (nsIPluginInstance*) (instance->ndata);
+ if (!xpcom_instance)
+ {
+ PLUGIN_ERROR ("xpcom_instance is NULL.");
+ goto cleanup_done;
+ }
+
+ xpcom_instance->GetPeer (&peer);
+ if (!peer)
+ {
+ PLUGIN_ERROR ("peer is NULL.");
+ goto cleanup_done;
+ }
+
+ u.info_field = &pluginTagInfo2;
+
+ result = peer->QueryInterface (kIPluginTagInfo2IID,
+ u.void_field);
+ if (result || !pluginTagInfo2)
+ {
+ PLUGIN_ERROR ("pluginTagInfo2 retrieval failed.");
+ goto cleanup_peer;
+ }
+
+ pluginTagInfo2->GetDocumentBase (&documentbase);
+
+ if (!documentbase)
+ {
+ PLUGIN_ERROR ("documentbase is NULL.");
+ goto cleanup_plugintaginfo2;
+ }
+
+ documentbase_copy = g_strdup (documentbase);
+
+ // Release references.
+ cleanup_plugintaginfo2:
+ NS_RELEASE (pluginTagInfo2);
+
+ cleanup_peer:
+ NS_RELEASE (peer);
+
+ cleanup_done:
+ PLUGIN_DEBUG ("plugin_get_documentbase return");
+
+ return documentbase_copy;
+}
+
+// This function shows a error message if the appletviewer has
+// not been installed. It returns true, if the user presses the
+// ok button.
+static bool
+plugin_failed ()
+{
+ GtkWidget* dialog = NULL;
+ GtkWidget* ok_button = NULL;
+
+ dialog = gtk_message_dialog_new (NULL,
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_NONE,
+ FAILURE_MESSAGE);
+ ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog),
+ GTK_STOCK_OK,
+ GTK_RESPONSE_OK);
+ gtk_widget_show_all (dialog);
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
+ {
+ gtk_widget_destroy (dialog);
+ return true;
+ }
+ return false;
+}
+
+// plugin_user_trusts_documentbase returns true if the given
+// documentbase is in the documentbase whitelist. Otherwise it asks
+// the user if he trusts the given documentbase by calling
+// plugin_ask_user_about_documentbase.
+static bool
+plugin_user_trusts_documentbase (char* documentbase)
+{
+ bool applet_in_whitelist = false;
+
+ // Check if documentbase is in whitelist.
+ while (true)
+ {
+ gchar* whitelist_entry = NULL;
+ gchar* newline_documentbase = NULL;
+
+ // If reading fails, break out of this loop with
+ // applet_in_whitelist still set to false.
+ if (g_io_channel_read_line (whitelist_file, &whitelist_entry,
+ NULL, NULL, &channel_error)
+ != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to read line from whitelist file",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to open whitelist file.");
+ g_free (whitelist_entry);
+ whitelist_entry = NULL;
+ break;
+ }
+
+ newline_documentbase = g_strdup_printf ("%s\n", documentbase);
+ if (!strcmp (newline_documentbase, whitelist_entry))
+ {
+ applet_in_whitelist = true;
+ g_free (newline_documentbase);
+ newline_documentbase = NULL;
+ g_free (whitelist_entry);
+ whitelist_entry = NULL;
+ break;
+ }
+ g_free (whitelist_entry);
+ whitelist_entry = NULL;
+ g_free (newline_documentbase);
+ newline_documentbase = NULL;
+ }
+
+ return applet_in_whitelist ? true
+ : plugin_ask_user_about_documentbase (documentbase);
+}
+
+// plugin_add_documentbase_to_whitelist adds the given documentbase to
+// the user's documentbase whitelist.
+static void
+plugin_add_documentbase_to_whitelist (char* documentbase)
+{
+ gsize bytes_written = 0;
+ char* newline_documentbase = NULL;
+ GIOStatus status = G_IO_STATUS_NORMAL;
+
+ newline_documentbase = g_strdup_printf ("%s\n", documentbase);
+ status = g_io_channel_write_chars (whitelist_file,
+ newline_documentbase, -1, &bytes_written,
+ &channel_error);
+ g_free (newline_documentbase);
+ newline_documentbase = NULL;
+
+ if (status != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Error writing to whitelist file",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Error writing to whitelist file.");
+ }
+
+ if (g_io_channel_flush (whitelist_file, &channel_error)
+ != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to write whitelist file",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to write whitelist file.");
+ }
+
+ if (g_io_channel_shutdown (whitelist_file, TRUE, &channel_error)
+ != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to close whitelist file",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to close whitelist file.");
+ }
+}
+
+// plugin_ask_user_about_documentbase puts up a dialog box that asks if the
+// user trusts applets from this documentbase. The user has three
+// options: "Cancel", "Trust Applet" and "Trust Applet and Add to
+// Whitelist". If the user selects Cancel (the default) then a
+// generic error code is returned from GCJ_New, telling the browser
+// that the applet failed to load. If the user selects "Trust Applet"
+// then plugin loading proceeds. If the user selects "Trust Applet
+// and Add to Whitelist" then this documentbase is added to the user's
+// applet whitelist and plugin loading proceeds.
+static bool
+plugin_ask_user_about_documentbase (char* documentbase)
+{
+ GtkWidget* dialog = NULL;
+ GtkWidget* ok_button = NULL;
+ GtkWidget* cancel_button = NULL;
+ GtkWidget* whitelist_button = NULL;
+ gint dialog_response = GTK_RESPONSE_NONE;
+
+ dialog = gtk_message_dialog_new (NULL,
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_NONE,
+ SECURITY_WARNING,
+ documentbase);
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+ SECURITY_DESCRIPTION);
+
+ cancel_button = gtk_dialog_add_button (GTK_DIALOG (dialog),
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL);
+ ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog),
+ RESPONSE_TRUST_APPLET,
+ GTK_RESPONSE_OK);
+ whitelist_button = gtk_dialog_add_button (GTK_DIALOG (dialog),
+ RESPONSE_TRUST_APPLET_ADD_TO_LIST,
+ GTK_RESPONSE_APPLY);
+ gtk_widget_grab_focus (cancel_button);
+
+ gtk_widget_show_all (dialog);
+ dialog_response = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ if (dialog_response == GTK_RESPONSE_CANCEL)
+ {
+ // The user does not trust this documentbase.
+ return false;
+ }
+ else if (dialog_response == GTK_RESPONSE_APPLY)
+ {
+ // The user wants this documentbase added to his documentbase
+ // whitelist.
+ plugin_add_documentbase_to_whitelist (documentbase);
+ }
+ // The user trusts this documentbase.
+ return true;
+}
+
+// plugin_in_pipe_callback is called when data is available on the
+// input pipe, or when the appletviewer crashes or is killed. It may
+// be called after data has been destroyed in which case it simply
+// returns FALSE to remove itself from the glib main loop.
+static gboolean
+plugin_in_pipe_callback (GIOChannel* source,
+ GIOCondition condition,
+ gpointer plugin_data)
+{
+ PLUGIN_DEBUG ("plugin_in_pipe_callback");
+
+ GCJPluginData* data = (GCJPluginData*) plugin_data;
+ gboolean keep_installed = TRUE;
+
+ // If data is NULL then GCJ_Destroy has already been called and
+ // plugin_in_pipe_callback is being called after plugin
+ // destruction. In that case all we need to do is return FALSE so
+ // that the plugin_in_pipe_callback watch is removed.
+ if (data)
+ {
+ // Critical region. Set or clear data->appletviewer_alive.
+ g_mutex_lock (data->appletviewer_mutex);
+
+ if (condition & G_IO_IN)
+ {
+ gchar* message = NULL;
+
+ if (g_io_channel_read_line (data->in_from_appletviewer,
+ &message, NULL, NULL,
+ &channel_error)
+ != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to read line from input channel",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to read line from input channel");
+ }
+ else
+ {
+ if (g_str_has_prefix (message, "url "))
+ {
+ gchar** parts = g_strsplit (message, " ", 3);
+ PLUGIN_DEBUG_TWO ("plugin_in_pipe_callback:"
+ " opening URL", parts[1]);
+ PLUGIN_DEBUG_TWO ("plugin_in_pipe_callback:"
+ " URL target", parts[2]);
+ // Open the URL in a new browser window.
+ NPError np_error =
+ (*browserFunctions.geturl) (data->owner, parts[1], parts[2]);
+ if (np_error != NPERR_NO_ERROR)
+ PLUGIN_ERROR ("Failed to load URL.");
+ g_strfreev (parts);
+ parts = NULL;
+ }
+ else if (g_str_has_prefix (message, "status "))
+ {
+ gchar** parts = g_strsplit (message, " ", 2);
+
+ PLUGIN_DEBUG_TWO ("plugin_in_pipe_callback:"
+ " setting status", parts[1]);
+ (*browserFunctions.status) (data->owner, parts[1]);
+ g_strfreev (parts);
+ parts = NULL;
+ }
+ g_print (" PIPE: plugin read %s\n", message);
+ }
+
+ g_free (message);
+ message = NULL;
+
+ keep_installed = TRUE;
+ }
+
+ if (condition & (G_IO_ERR | G_IO_HUP))
+ {
+ PLUGIN_DEBUG ("appletviewer has stopped.");
+ data->appletviewer_alive = FALSE;
+ keep_installed = FALSE;
+ }
+ g_mutex_unlock (data->appletviewer_mutex);
+ }
+
+ PLUGIN_DEBUG ("plugin_in_pipe_callback return");
+
+ return keep_installed;
+}
+
+// plugin_out_pipe_callback is called when the appletviewer crashes or
+// is killed. It may be called after data has been destroyed in which
+// case it simply returns FALSE to remove itself from the glib main
+// loop.
+static gboolean
+plugin_out_pipe_callback (GIOChannel* source,
+ GIOCondition condition,
+ gpointer plugin_data)
+{
+ PLUGIN_DEBUG ("plugin_out_pipe_callback");
+
+ GCJPluginData* data = (GCJPluginData*) plugin_data;
+
+ // If data is NULL then GCJ_Destroy has already been called and
+ // plugin_out_pipe_callback is being called after plugin
+ // destruction. In that case all we need to do is return FALSE so
+ // that the plugin_out_pipe_callback watch is removed.
+ if (data)
+ {
+ // Critical region. Clear data->appletviewer_alive.
+ g_mutex_lock (data->appletviewer_mutex);
+
+ PLUGIN_DEBUG ("plugin_out_pipe_callback: appletviewer has stopped.");
+ data->appletviewer_alive = FALSE;
+
+ g_mutex_unlock (data->appletviewer_mutex);
+ }
+
+ PLUGIN_DEBUG ("plugin_out_pipe_callback return");
+
+ return FALSE;
+}
+
+static NPError
+plugin_start_appletviewer (GCJPluginData* data)
+{
+ PLUGIN_DEBUG ("plugin_start_appletviewer");
+ NPError error = NPERR_NO_ERROR;
+
+ if (!data->appletviewer_alive)
+ {
+ gchar* command_line[3] = { NULL, NULL, NULL };
+
+ command_line[0] = g_strdup (APPLETVIEWER_EXECUTABLE);
+ // Output from plugin's perspective is appletviewer's input.
+ // Input from plugin's perspective is appletviewer's output.
+ command_line[1] = g_strdup_printf ("--plugin=%s,%s",
+ data->out_pipe_name,
+ data->in_pipe_name);
+ command_line[2] = NULL;
+
+ if (!g_spawn_async (NULL, command_line, NULL, (GSpawnFlags) 0,
+ NULL, NULL, NULL, &channel_error))
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to spawn applet viewer",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to spawn applet viewer");
+ error = NPERR_GENERIC_ERROR;
+ goto cleanup;
+ }
+
+ cleanup:
+ g_free (command_line[0]);
+ command_line[0] = NULL;
+ g_free (command_line[1]);
+ command_line[1] = NULL;
+ g_free (command_line[2]);
+ command_line[2] = NULL;
+ }
+
+ PLUGIN_DEBUG ("plugin_start_appletviewer return");
+ return error;
+}
+
+// Build up the applet tag string that we'll send to the applet
+// viewer.
+static gchar*
+plugin_create_applet_tag (int16 argc, char* argn[], char* argv[])
+{
+ PLUGIN_DEBUG ("plugin_create_applet_tag");
+
+ gchar* applet_tag = g_strdup ("<EMBED ");
+ gchar* parameters = g_strdup ("");
+
+ for (int16 i = 0; i < argc; i++)
+ {
+ if (!g_ascii_strcasecmp (argn[i], "code"))
+ {
+ gchar* code = g_strdup_printf ("CODE=\"%s\" ", argv[i]);
+ applet_tag = g_strconcat (applet_tag, code, NULL);
+ g_free (code);
+ code = NULL;
+ }
+ else if (!g_ascii_strcasecmp (argn[i], "codebase"))
+ {
+ gchar* codebase = g_strdup_printf ("CODEBASE=\"%s\" ", argv[i]);
+ applet_tag = g_strconcat (applet_tag, codebase, NULL);
+ g_free (codebase);
+ codebase = NULL;
+ }
+ else if (!g_ascii_strcasecmp (argn[i], "archive"))
+ {
+ gchar* archive = g_strdup_printf ("ARCHIVE=\"%s\" ", argv[i]);
+ applet_tag = g_strconcat (applet_tag, archive, NULL);
+ g_free (archive);
+ archive = NULL;
+ }
+ else if (!g_ascii_strcasecmp (argn[i], "width"))
+ {
+ gchar* width = g_strdup_printf ("WIDTH=\"%s\" ", argv[i]);
+ applet_tag = g_strconcat (applet_tag, width, NULL);
+ g_free (width);
+ width = NULL;
+ }
+ else if (!g_ascii_strcasecmp (argn[i], "height"))
+ {
+ gchar* height = g_strdup_printf ("HEIGHT=\"%s\" ", argv[i]);
+ applet_tag = g_strconcat (applet_tag, height, NULL);
+ g_free (height);
+ height = NULL;
+ }
+ else
+ {
+ // Escape the parameter value so that line termination
+ // characters will pass through the pipe.
+ if (argv[i] != '\0')
+ {
+ gchar* escaped = NULL;
+
+ escaped = g_strescape (argv[i], NULL);
+ parameters = g_strconcat (parameters, "<PARAM NAME=\"", argn[i],
+ "\" VALUE=\"", escaped, "\">", NULL);
+
+ g_free (escaped);
+ escaped = NULL;
+ }
+ }
+ }
+
+ applet_tag = g_strconcat (applet_tag, ">", parameters, "</EMBED>", NULL);
+
+ g_free (parameters);
+ parameters = NULL;
+
+ PLUGIN_DEBUG ("plugin_create_applet_tag return");
+
+ return applet_tag;
+}
+
+// plugin_send_message_to_appletviewer must be called while holding
+// data->appletviewer_mutex.
+static void
+plugin_send_message_to_appletviewer (GCJPluginData* data, gchar const* message)
+{
+ PLUGIN_DEBUG ("plugin_send_message_to_appletviewer");
+
+ if (data->appletviewer_alive)
+ {
+ gchar* newline_message = NULL;
+ gsize bytes_written = 0;
+
+ // Send message to appletviewer.
+ newline_message = g_strdup_printf ("%s\n", message);
+
+ // g_io_channel_write_chars will return something other than
+ // G_IO_STATUS_NORMAL if not all the data is written. In that
+ // case we fail rather than retrying.
+ if (g_io_channel_write_chars (data->out_to_appletviewer,
+ newline_message, -1, &bytes_written,
+ &channel_error)
+ != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to write bytes to output channel",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to write bytes to output channel");
+ }
+
+ if (g_io_channel_flush (data->out_to_appletviewer, &channel_error)
+ != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to flush bytes to output channel",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to flush bytes to output channel");
+ }
+ g_free (newline_message);
+ newline_message = NULL;
+
+ g_print (" PIPE: plugin wrote %s\n", message);
+ }
+
+ PLUGIN_DEBUG ("plugin_send_message_to_appletviewer return");
+}
+
+// Stop the appletviewer process. When this is called the
+// appletviewer can be in any of three states: running, crashed or
+// hung. If the appletviewer is running then sending it "shutdown"
+// will cause it to exit. This will cause
+// plugin_out_pipe_callback/plugin_in_pipe_callback to be called and
+// the input and output channels to be shut down. If the appletviewer
+// has crashed then plugin_out_pipe_callback/plugin_in_pipe_callback
+// would already have been called and data->appletviewer_alive cleared
+// in which case this function simply returns. If the appletviewer is
+// hung then this function will be successful and the input and output
+// watches will be removed by plugin_data_destroy.
+// plugin_stop_appletviewer must be called with
+// data->appletviewer_mutex held.
+static void
+plugin_stop_appletviewer (GCJPluginData* data)
+{
+ PLUGIN_DEBUG ("plugin_stop_appletviewer");
+
+ if (data->appletviewer_alive)
+ {
+ // Shut down the appletviewer.
+ gsize bytes_written = 0;
+
+ if (data->out_to_appletviewer)
+ {
+ if (g_io_channel_write_chars (data->out_to_appletviewer, "shutdown",
+ -1, &bytes_written, &channel_error)
+ != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to write shutdown message to"
+ " appletviewer", channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to write shutdown message to");
+ }
+
+ if (g_io_channel_flush (data->out_to_appletviewer, &channel_error)
+ != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to write shutdown message to"
+ " appletviewer", channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to write shutdown message to");
+ }
+
+ if (g_io_channel_shutdown (data->out_to_appletviewer,
+ TRUE, &channel_error)
+ != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to shut down appletviewer"
+ " output channel", channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to shut down appletviewer");
+ }
+ }
+
+ if (data->in_from_appletviewer)
+ {
+ if (g_io_channel_shutdown (data->in_from_appletviewer,
+ TRUE, &channel_error)
+ != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to shut down appletviewer"
+ " input channel", channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to shut down appletviewer");
+ }
+ }
+ }
+
+ PLUGIN_DEBUG ("plugin_stop_appletviewer return");
+}
+
+static void
+plugin_data_destroy (GCJPluginData** data)
+{
+ PLUGIN_DEBUG ("plugin_data_destroy");
+
+ GCJPluginData* tofree = *data;
+
+ tofree->window_handle = NULL;
+ tofree->window_height = 0;
+ tofree->window_width = 0;
+
+ // Copied from GCJ_New.
+
+ // cleanup_in_watch_source:
+ // Removing a source is harmless if it fails since it just means the
+ // source has already been removed.
+ g_source_remove (tofree->in_watch_source);
+ tofree->in_watch_source = 0;
+
+ // cleanup_in_from_appletviewer:
+ if (tofree->in_from_appletviewer)
+ g_io_channel_unref (tofree->in_from_appletviewer);
+ tofree->in_from_appletviewer = NULL;
+
+ // cleanup_out_watch_source:
+ g_source_remove (tofree->out_watch_source);
+ tofree->out_watch_source = 0;
+
+ // cleanup_out_to_appletviewer:
+ if (tofree->out_to_appletviewer)
+ g_io_channel_unref (tofree->out_to_appletviewer);
+ tofree->out_to_appletviewer = NULL;
+
+ // cleanup_out_pipe:
+ // Delete output pipe.
+ unlink (tofree->out_pipe_name);
+
+ // cleanup_out_pipe_name:
+ g_free (tofree->out_pipe_name);
+ tofree->out_pipe_name = NULL;
+
+ // cleanup_in_pipe:
+ // Delete input pipe.
+ unlink (tofree->in_pipe_name);
+
+ // cleanup_in_pipe_name:
+ g_free (tofree->in_pipe_name);
+ tofree->in_pipe_name = NULL;
+
+ // cleanup_appletviewer_mutex:
+ g_free (tofree->appletviewer_mutex);
+ tofree->appletviewer_mutex = NULL;
+
+ // cleanup_instance_string:
+ g_free (tofree->instance_string);
+ tofree->instance_string = NULL;
+
+ // cleanup_data:
+ // Eliminate back-pointer to plugin instance.
+ tofree->owner = NULL;
+ (*browserFunctions.memfree) (tofree);
+ tofree = NULL;
+
+ PLUGIN_DEBUG ("plugin_data_destroy return");
+}
+
+// FACTORY FUNCTIONS
+
+// Provides the browser with pointers to the plugin functions that we
+// implement and initializes a local table with browser functions that
+// we may wish to call. Called once, after browser startup and before
+// the first plugin instance is created.
+NPError
+NP_Initialize (NPNetscapeFuncs* browserTable, NPPluginFuncs* pluginTable)
+{
+ PLUGIN_DEBUG ("NP_Initialize");
+
+ if (initialized)
+ return NPERR_NO_ERROR;
+ else if ((browserTable == NULL) || (pluginTable == NULL))
+ {
+ PLUGIN_ERROR ("Browser or plugin function table is NULL.");
+
+ return NPERR_INVALID_FUNCTABLE_ERROR;
+ }
+
+ // Ensure that the major version of the plugin API that the browser
+ // expects is not more recent than the major version of the API that
+ // we've implemented.
+ if ((browserTable->version >> 8) > NP_VERSION_MAJOR)
+ {
+ PLUGIN_ERROR ("Incompatible version.");
+
+ return NPERR_INCOMPATIBLE_VERSION_ERROR;
+ }
+
+ // Ensure that the plugin function table we've received is large
+ // enough to store the number of functions that we may provide.
+ if (pluginTable->size < sizeof (NPPluginFuncs))
+ {
+ PLUGIN_ERROR ("Invalid plugin function table.");
+
+ return NPERR_INVALID_FUNCTABLE_ERROR;
+ }
+
+ // Ensure that the browser function table is large enough to store
+ // the number of browser functions that we may use.
+ if (browserTable->size < sizeof (NPNetscapeFuncs))
+ {
+ PLUGIN_ERROR ("Invalid browser function table.");
+
+ return NPERR_INVALID_FUNCTABLE_ERROR;
+ }
+
+ // Make sure the plugin data directory exists, creating it if
+ // necessary.
+ if (!g_file_test (PLUGIN_DATA_DIRECTORY,
+ (GFileTest) (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
+ {
+ int file_error = 0;
+
+ file_error = g_mkdir (PLUGIN_DATA_DIRECTORY, 0700);
+ if (file_error != 0)
+ {
+ PLUGIN_ERROR_TWO ("Failed to create data directory "
+ PLUGIN_DATA_DIRECTORY " ",
+ strerror (errno));
+ return NPERR_GENERIC_ERROR;
+ }
+ }
+
+ // Open the user's documentbase whitelist.
+ whitelist_file = g_io_channel_new_file (WHITELIST_FILENAME,
+ "a+", &channel_error);
+ if (!whitelist_file)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to open whitelist file "
+ WHITELIST_FILENAME " ",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to open whitelist file "
+ WHITELIST_FILENAME);
+
+ return NPERR_GENERIC_ERROR;
+ }
+
+ // Store in a local table the browser functions that we may use.
+ browserFunctions.version = browserTable->version;
+ browserFunctions.size = browserTable->size;
+ browserFunctions.posturl = browserTable->posturl;
+ browserFunctions.geturl = browserTable->geturl;
+ browserFunctions.geturlnotify = browserTable->geturlnotify;
+ browserFunctions.requestread = browserTable->requestread;
+ browserFunctions.newstream = browserTable->newstream;
+ browserFunctions.write = browserTable->write;
+ browserFunctions.destroystream = browserTable->destroystream;
+ browserFunctions.status = browserTable->status;
+ browserFunctions.uagent = browserTable->uagent;
+ browserFunctions.memalloc = browserTable->memalloc;
+ browserFunctions.memfree = browserTable->memfree;
+ browserFunctions.memflush = browserTable->memflush;
+ browserFunctions.reloadplugins = browserTable->reloadplugins;
+ browserFunctions.getvalue = browserTable->getvalue;
+
+ // Return to the browser the plugin functions that we implement.
+ pluginTable->version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR;
+ pluginTable->size = sizeof (NPPluginFuncs);
+ pluginTable->newp = NewNPP_NewProc (GCJ_New);
+ pluginTable->destroy = NewNPP_DestroyProc (GCJ_Destroy);
+ pluginTable->setwindow = NewNPP_SetWindowProc (GCJ_SetWindow);
+ pluginTable->newstream = NewNPP_NewStreamProc (GCJ_NewStream);
+ pluginTable->destroystream = NewNPP_DestroyStreamProc (GCJ_DestroyStream);
+ pluginTable->asfile = NewNPP_StreamAsFileProc (GCJ_StreamAsFile);
+ pluginTable->writeready = NewNPP_WriteReadyProc (GCJ_WriteReady);
+ pluginTable->write = NewNPP_WriteProc (GCJ_Write);
+ pluginTable->print = NewNPP_PrintProc (GCJ_Print);
+ pluginTable->urlnotify = NewNPP_URLNotifyProc (GCJ_URLNotify);
+ pluginTable->getvalue = NewNPP_GetValueProc (GCJ_GetValue);
+
+ initialized = true;
+ plugin_instance_mutex = g_mutex_new ();
+
+ PLUGIN_DEBUG ("NP_Initialize: using " APPLETVIEWER_EXECUTABLE ".");
+
+ PLUGIN_DEBUG ("NP_Initialize return");
+
+ return NPERR_NO_ERROR;
+}
+
+// Returns a string describing the MIME type that this plugin
+// handles.
+char*
+NP_GetMIMEDescription (void)
+{
+ PLUGIN_DEBUG ("NP_GetMIMEDescription");
+
+ PLUGIN_DEBUG ("NP_GetMIMEDescription return");
+
+ return (char*) PLUGIN_MIME_DESC;
+}
+
+// Returns a value relevant to the plugin as a whole. The browser
+// calls this function to obtain information about the plugin.
+NPError
+NP_GetValue (void* future, NPPVariable variable, void* value)
+{
+ PLUGIN_DEBUG ("NP_GetValue");
+
+ NPError result = NPERR_NO_ERROR;
+ gchar** char_value = (gchar**) value;
+
+ switch (variable)
+ {
+ case NPPVpluginNameString:
+ PLUGIN_DEBUG ("NP_GetValue: returning plugin name.");
+ *char_value = g_strdup (PLUGIN_NAME " " PACKAGE_VERSION);
+ break;
+
+ case NPPVpluginDescriptionString:
+ PLUGIN_DEBUG ("NP_GetValue: returning plugin description.");
+ *char_value = g_strdup (PLUGIN_DESC);
+ break;
+
+ default:
+ PLUGIN_ERROR ("Unknown plugin value requested.");
+ result = NPERR_GENERIC_ERROR;
+ break;
+ }
+
+ PLUGIN_DEBUG ("NP_GetValue return");
+
+ return result;
+}
+
+// Shuts down the plugin. Called after the last plugin instance is
+// destroyed.
+NPError
+NP_Shutdown (void)
+{
+ PLUGIN_DEBUG ("NP_Shutdown");
+
+ // Free mutex.
+ g_mutex_free (plugin_instance_mutex);
+ plugin_instance_mutex = NULL;
+
+ g_io_channel_close (whitelist_file);
+
+ PLUGIN_DEBUG ("NP_Shutdown return");
+
+ return NPERR_NO_ERROR;
+}
diff --git a/resource/gnu/classpath/tools/appletviewer/MessagesBundle.properties b/resource/gnu/classpath/tools/appletviewer/MessagesBundle.properties
index b2365a8d7..bbd7618a6 100644
--- a/resource/gnu/classpath/tools/appletviewer/MessagesBundle.properties
+++ b/resource/gnu/classpath/tools/appletviewer/MessagesBundle.properties
@@ -1,51 +1,50 @@
-/* MessagesBundle.properties -- English language messages
- Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+# MessagesBundle.properties -- English language messages
+# Copyright (C) 2004, 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.
-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. */
-
-gcjwebplugin.code_description= Code attribute
-gcjwebplugin.codebase_description= Codebase attribute
-gcjwebplugin.archive_description= Archive attribute
-gcjwebplugin.param_description= Parameter arguments
-gcjwebplugin.width_description= Width attribute
-gcjwebplugin.height_description= Height attribute
-gcjwebplugin.plugin_description= Enable plugin mode
-gcjwebplugin.verbose_description= Enable verbose mode
-gcjwebplugin.debug_description= For appletviewer compatibility
-gcjwebplugin.encoding_description= Specify character encoding used by HTML files
-gcjwebplugin.j_description= Pass argument to the Java runtime
+gcjwebplugin.code_description=specify the code attribute
+gcjwebplugin.codebase_description=specify the codebase attribute
+gcjwebplugin.archive_description=specify the archive attribute
+gcjwebplugin.width_description=specify the width attribute
+gcjwebplugin.height_description=specify the height attribute
+gcjwebplugin.param_description=specify the parameter arguments
+gcjwebplugin.plugin_description=enable plugin mode
+gcjwebplugin.verbose_description=enable verbose mode
+gcjwebplugin.debug_description=enable debugging mode (not implemented)
+gcjwebplugin.encoding_description=specify the HTML character encoding
gcjwebplugin.no_input_files=appletviewer: no input files
diff --git a/resource/gnu/classpath/tools/appletviewer/MessagesBundle_de.properties b/resource/gnu/classpath/tools/appletviewer/MessagesBundle_de.properties
index fc61ecc5b..036b86f30 100644
--- a/resource/gnu/classpath/tools/appletviewer/MessagesBundle_de.properties
+++ b/resource/gnu/classpath/tools/appletviewer/MessagesBundle_de.properties
@@ -1,41 +1,41 @@
-/* MessagesBundle_de.properties -- German language messages
- Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+# MessagesBundle_de.properties -- German language messages
+# Copyright (C) 2004, 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.
-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. */
-
-/* FIXME: rewrite this */
+# FIXME: rewrite this:
gcjwebplugin.help.0=Syntax: appletviewer [Optionen] <Dateiname>.class | <Dateiname>.html... | URL...
gcjwebplugin.help.1=Optionen:
gcjwebplugin.help.2= --help Diese Hilfe anzeigen and beenden
diff --git a/resource/gnu/classpath/tools/getopt/Messages.properties b/resource/gnu/classpath/tools/getopt/Messages.properties
new file mode 100644
index 000000000..42827e6e3
--- /dev/null
+++ b/resource/gnu/classpath/tools/getopt/Messages.properties
@@ -0,0 +1,49 @@
+# MessagesBundle.properties -- English language messages
+# 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.
+
+Parser.StdOptions=Standard options
+Parser.PrintHelp=print this help, then exit
+Parser.PrintVersion=print version number, then exit
+Parser.JArgument=pass argument to the Java runtime
+Parser.JName=OPTION
+Parser.ArgReqd=option ''{0}'' requires an argument
+Parser.Unrecognized=unrecognized option ''{0}''
+Parser.NoArg=option ''{0}'' doesn''t allow an argument
+Parser.UnrecDash=unrecognized option ''-{0}''
+Parser.TryHelpShort=Try ''{0} -help'' for more information
+Parser.TryHelpLong=Try ''{0} --help'' for more information
+ClasspathToolParser.VersionFormat={0} (GNU Classpath) {1}\n\nCopyright 2006 Free Software Foundation, Inc.\nThis is free software; see the source for copying conditions. There is NO\nwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
diff --git a/resource/gnu/classpath/tools/jar/messages.properties b/resource/gnu/classpath/tools/jar/messages.properties
new file mode 100644
index 000000000..e589a210f
--- /dev/null
+++ b/resource/gnu/classpath/tools/jar/messages.properties
@@ -0,0 +1,71 @@
+# messages.properties -- English language messages
+# 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.
+
+Creator.Ignoring=ignoring entry {0}
+Creator.Adding=adding: {0} (in={1,number,integer}) (out={2,number,integer}) (stored {3,number,integer}%)
+Extractor.Created=\ \ created: {0}
+Extractor.Extracted=\ extracted: {0}
+Extractor.Inflated=\ \ inflated: {0}
+Indexer.Indexing=indexing: {0}
+Main.ArchiveAlreadySet=archive file name already set to {0}
+Main.ModeAlreaySet=operation mode already specified
+Main.MustSpecify=must specify one of -t, -c, -u, -x, or -i
+Main.TwoArgsReqd=-C argument requires both directory and filename
+Main.CantHaveBoth=can't specify both -m and -M
+Main.NoFilesWithi=can't specify file arguments when using -i
+Main.NoMAndi=can't specify -M with -i
+Main.AnotherNomAndi=can't specify -m with -i
+Main.Usage=Usage: jar -ctxui [OPTIONS] jar-file [-C DIR FILE] FILE...
+Main.OpMode=Operation mode
+Main.Create=create a new archive
+Main.Extract=extract from archive
+Main.List=list archive contents
+Main.Update=update archive
+Main.Index=compute archive index
+Main.FileArg=FILE
+Main.OpMods=Operation modifiers
+Main.ArchiveName=specify archive file name
+Main.FileArg2=FILE
+Main.NoZip=store only; no ZIP compression
+Main.Verbose=verbose operation
+Main.NoManifest=do not create a manifest file
+Main.ManifestName=specify manifest file
+Main.ManifestArgName=FILE
+Main.FileNameGroup=File name selection
+Main.ChangeDir=change to directory before the next file
+Main.ChangeDirArg=DIR FILE
+Main.InternalError=jar: internal error:
diff --git a/resource/gnu/classpath/tools/jarsigner/MessageBundle.properties b/resource/gnu/classpath/tools/jarsigner/MessageBundle.properties
deleted file mode 100644
index 902166d5f..000000000
--- a/resource/gnu/classpath/tools/jarsigner/MessageBundle.properties
+++ /dev/null
@@ -1,33 +0,0 @@
-# default locale messages for gnu.classpath.tools.jarsigner package
-
-Main.7=jarsigner:
-Main.9=jarsigner error:
-Main.70=JAR file [{0}] is NOT a file object
-Main.72=JAR file [{0}] is NOT readable
-#Main.85=Option '-keystore' is not defined or is an empty string, and 'user.home' is unknown
-Main.85=Unable to locate a valid key store
-Main.92=Enter key store password:
-Main.6=Designated alias [{0}] MUST be known to the key store in use
-Main.95=Designated alias [{0}] MUST be an Alias of a Key Entry
-Main.97=Enter key password for <{0}>:
-Main.99=Key associated with [{0}] MUST be a private key
-
-JarSigner.1=\ \ signing:
-JarSigner.2=\ updating:
-JarSigner.8=\ \ \ adding:
-JarSigner.11=\ \ \ adding:
-JarSigner.14=jar signed.
-
-JarVerifier.2=jar is not signed.--no signature files found.
-JarVerifier.3=jar verification failed.
-JarVerifier.4=jar partially verified --{0,numer} of {1,number} signers.
-JarVerifier.7=jar verified --{0,number} signer(s).
-JarVerifier.13=Signature Block missing for {0}
-JarVerifier.14=At least one SignerInfo element MUST be present in a Signature Block (.DSA file)
-JarVerifier.16=Missing EncryptedDigest in Signature Block (.DSA file) first SignerInfo element
-
-SFHelper.1=Helper is NOT finished
-SFHelper.4=.SF file has NOT been generated
-SFHelper.6=Unknown or unsupported private key algorithm
-SFHelper.9=Helper is NOT ready
-SFHelper.10=Helper is NOT started
diff --git a/resource/gnu/classpath/tools/jarsigner/messages.properties b/resource/gnu/classpath/tools/jarsigner/messages.properties
new file mode 100644
index 000000000..4383256de
--- /dev/null
+++ b/resource/gnu/classpath/tools/jarsigner/messages.properties
@@ -0,0 +1,122 @@
+# messages.properties -- English language messages and message formats
+# 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.
+#
+# for gnu.classpath.tools.jarsigner package
+#
+
+Main.7=jarsigner:
+Main.9=jarsigner error:
+Main.70=JAR file [{0}] is NOT a file object
+Main.72=JAR file [{0}] is NOT readable
+#Main.85=Option '-keystore' is not defined or is an empty string, and 'user.home' is unknown
+Main.85=Unable to locate a valid key store
+Main.92=Enter key store password:
+Main.6=Designated alias [{0}] MUST be known to the key store in use
+Main.2=\
+Usage: jarsigner [OPTION]... FILE ALIAS\n\
+\ \ \ \ \ \ \ \ jarsigner -verify [OPTION]... FILE\n\
+Java ARchive (JAR) file signing and verification tool.\n\
+\n\
+FILE is the .JAR file to sign or to verify.\n\
+\n\
+ALIAS must be a known Alias of a Key Entry in the designated key store. The \
+private key material associated with this Alias is used for signing FILE. if \
+ALIAS is required, but was omitted, "mykey" will be used instead.
+Main.1=Please report bugs at http://www.gnu.org/software/classpath/bugs.html
+Main.0=Signing options
+Main.95=Designated alias [{0}] MUST be an Alias of a Key Entry
+Main.97=Enter key password for <{0}>:
+Main.99=Key associated with [{0}] MUST be a private key
+Main.101=Location of the key store to use. The default value is a file-based \
+scheme whose path is the file named ".keystore" in your home directory.\n\
+If URL is malformed, the tool will use URL as a file-name of a key store; \
+i.e. as if the protocol was "file:".
+Main.102=URL
+Main.104=Type of the key store to use. If omitted, the default value is that \
+of the property "keystore.type" in the security properties file.
+Main.105=STORE_TYPE
+Main.107=Password to unlock the key store. If omitted, you will be prompted \
+to provide a password.
+Main.108=PASSWORD
+Main.110=Password to unlock the Key Entry associated with ALIAS. If omitted, \
+the tool will use the same password protecting the key store. If this fails, \
+you will be prompted to provide a password.
+Main.111=PASSWORD
+Main.113=A literal to construct file names for both the .SF and .DSA signature \
+files --which will be placed in the META-INF directory of the signed JAR. \
+Permissible characters are in the range [a-zA-Z0-9_-].\n\
+If omitted, the first 8 characters of ALIAS will be used. Characters outside \
+that range will be replaced by underscores.
+Main.114=NAME
+Main.116=Name of the signed JAR file. If omitted, the signed JAR will be \
+named the same as FILE; i.e. the input file will be replaced with its signed \
+copy.
+Main.117=FILE
+Main.118=Verification options
+Main.120=Verify an already signed FILE.
+Main.122=Use with -verbose to see more detailed information about the \
+certificates of ALIAS.
+Main.123=Common options
+Main.125=Output more verbose messages during processing.
+Main.127=Include --otherwise do not-- the .SF file in the .DSA generated file.
+Main.129=Include in the .SF generated file --otherwise do not-- a header \
+containing a hash of the whole manifest file.
+Main.131=Fully qualified class name of a Security Provider to add to the JVM \
+in-use.
+Main.132=PROVIDER_CLASS_NAME
+Main.133=Missing FILE argument.
+
+JarSigner.1=\ \ signing:
+JarSigner.2=\ updating:
+JarSigner.8=\ \ \ adding:
+JarSigner.14=Jar signed.
+
+JarVerifier.2=Jar is not signed --no signature files found.
+JarVerifier.3=Jar verification failed.
+JarVerifier.4=Jar partially verified --{0,numer} of {1,number} signers.
+JarVerifier.7=Jar verified --{0,number} signer(s).
+JarVerifier.13=Signature Block missing for {0}
+JarVerifier.14=At least one SignerInfo element MUST be present in a Signature \
+Block (.DSA file)
+JarVerifier.16=Missing EncryptedDigest in Signature Block (.DSA file) first \
+SignerInfo element
+
+SFHelper.1=Helper is NOT finished
+SFHelper.4=.SF file has NOT been generated
+SFHelper.6=Unknown or unsupported private key algorithm
+SFHelper.9=Helper is NOT ready
+SFHelper.10=Helper is NOT started
diff --git a/resource/gnu/classpath/tools/keytool/MessageBundle.properties b/resource/gnu/classpath/tools/keytool/MessageBundle.properties
deleted file mode 100644
index 2dd3ce2fc..000000000
--- a/resource/gnu/classpath/tools/keytool/MessageBundle.properties
+++ /dev/null
@@ -1,95 +0,0 @@
-# default locale messages for gnu.classpath.tools.keytool package
-
-Main.6=keytool:
-Main.8=keytool error:
-
-Command.19=Failed creating new file at {0}
-Command.20=Unable to find a suitable signature algorithm named {0}, although we found a key-pair generation algorithm named {1}
-Command.21=Enter key password for <{0}>:
-Command.23=A correct key password MUST be provided
-Command.24=Enter key store password:
-#Command.36=Option '-keystore' is undefined, or is an empty string, and 'user.home' is unknown
-Command.36=Unable to locate a valid key store
-Command.40=Provider fully qualified class name:
-Command.42=File object [{0}] exists but is NOT a file
-Command.44=File [{0}] exists but is NOT writable
-Command.46=File object [{0}] MUST be an existing readable file
-Command.48=Signature algorithm is missing and private key is of unknown or unsupported type
-Command.51=Validity period MUST be greater than zero
-Command.52=Unable to get signature algorithm name
-Command.60=Unknown or unsupported signature algorithm: {0}
-Command.63=Saving key store at {0}
-Command.66=Owner: {0}
-Command.67=Issuer: {0}
-Command.68=Serial number: {0,number}
-Command.69=Valid from: {0,date,full} - {0,time,full}
-Command.70=\ \ \ \ \ until: {0,date,full} - {0,time,full}
-Command.71=Certificate fingerprints
-Command.72=\ \ \ \ \ \ MD5: {0}
-Command.73=\ \ SHA-160: {0}
-Command.75=Alias [{0}] MUST be knwon to the key store
-Command.77=Alias [{0}] MUST be associated with a Key Entry
-
-CertReqCmd.27=Certification request stored in {0}
-CertReqCmd.28=Submit this to your CA
-
-DeleteCmd.19=Enter the Alias to delete:
-DeleteCmd.20=Alias MUST NOT be null or an empty string
-
-GenKeyCmd.0=\nYou are about to enter information that will be incorporated into\n\
-your certificate request. This information is what is called a\n\
-Distinguished Name or DN. There are quite a few fields but you\n\
-can use supplied default values, displayed between brackets, by just\n\
-hitting <Enter>, or blank the field by entering the <.> character\n\
-before hitting <Enter>.\n\n
-GenKeyCmd.6=The Sample Company
-GenKeyCmd.7=Sydney
-GenKeyCmd.8=NSW
-GenKeyCmd.9=AU
-GenKeyCmd.10=Common Name (hostname, IP, or your name):
-GenKeyCmd.11=Organization Name (company) [{0}]:
-GenKeyCmd.13=Organizational Unit Name (department, division):
-GenKeyCmd.14=Locality Name (city, district) [{0}]:
-GenKeyCmd.16=State or Province Name (full name) [{0}]:
-GenKeyCmd.18=Country Name (2 letter code) [{0}]:
-GenKeyCmd.54=Key size MUST be greater than zero
-
-StorePasswdCmd.19=Too many failed attempts
-StorePasswdCmd.20=Enter new key store password:
-StorePasswdCmd.21=Password MUST be at least 6 characters.
-StorePasswdCmd.22=New password MUST be different than the old one.
-StorePasswdCmd.23=Re-enter new key store password:
-StorePasswdCmd.24=Passwords MUST be the same in both attempts.
-
-KeyPasswdCmd.24=Enter new key password for <{0}>:
-KeyPasswdCmd.28=Re-enter new key password for <{0}>:
-
-KeyCloneCmd.23=Destination Alias MUST NOT exist in key store
-KeyCloneCmd.26=Enter destination alias:
-KeyCloneCmd.27=Destination alias MUST NOT be null nor empty
-KeyCloneCmd.28=Enter new key password for <{0}> [{1}]:
-
-ListCmd.21=Key store type: {0}
-ListCmd.22=Key store provider: {0}
-ListCmd.24=Key store contains {0,number} entry(ies)
-ListCmd.30=Alias name: {0}
-ListCmd.31=Creation timestamp: {0,date,full} - {0,time,full}
-ListCmd.32=Entry type: trusted-certificate
-ListCmd.33=Entry type: key-entry
-ListCmd.34=Alias [{0}] is unknown to the key store
-ListCmd.38=Certificate chain length: {0,number}
-ListCmd.39=Certificate[1]:
-ListCmd.40=Certificate[{0,number}]:
-ListCmd.42=*******************************************
-ListCmd.43=-----BEGIN CERTIFICATE-----
-ListCmd.44=-----END CERTIFICATE-----
-ListCmd.45=Certificate fingerprint (MD5): {0}
-
-ImportCmd.34=Failed to establish chain-of-trust from reply
-ImportCmd.37=Unable to find anchor certificate for {0}
-ImportCmd.38=Public keys, in key store and certificate, MUST be of the same type
-ImportCmd.32=Can this certificate be trusted?
-ImportCmd.40=Key entry associated with {0} has an unknown or unsupported public key type {1}
-ImportCmd.41=Public keys, in key store and certificate, MUST be the same
-ImportCmd.29=Certificate was added to the key store
-ImportCmd.28=Certificate was not added to the key store
diff --git a/resource/gnu/classpath/tools/keytool/messages.properties b/resource/gnu/classpath/tools/keytool/messages.properties
new file mode 100644
index 000000000..71b70a766
--- /dev/null
+++ b/resource/gnu/classpath/tools/keytool/messages.properties
@@ -0,0 +1,542 @@
+# messages.properties -- English language messages and message formats
+# 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.
+#
+# for gnu.classpath.tools.keytool package
+#
+
+Main.6=keytool: {0}
+Main.8=keytool error: {0}
+Main.18=Unrecognized command: {0}
+Main.19=Usage: keytool [COMMAND] [-- COMMAND]...\n\
+Manage private keys and public certificates.
+Main.20=Please report bugs at http://www.gnu.org/software/classpath/bugs.html
+Main.21=Available commands
+Main.22=Generate a Key Entry, eventually creating a key store.\n\
+[-alias ALIAS] [-keyalg ALGORITHM] [-keysize KEY_SIZE]\n\
+[-sigalg ALGORITHM] [-dname NAME] [-keypass PASSWORD]\n\
+[-validity DAY_COUNT] [-storetype STORE_TYPE]\n\
+[-keystore URL] [-storepass PASSWORD]\n\
+[-provider PROVIDER_CLASS_NAME] [-v].
+Main.23=Add Key Entries and Trusted Certificates.\n\
+[-alias ALIAS] [-file FILE] [-keypass PASSWORD]\n\
+[-noprompt] [-trustcacerts] [-storetype STORE_TYPE]\n\
+[-keystore URL] [-storepass PASSWORD]\n\
+[-provider PROVIDER_CLASS_NAME] [-v].
+Main.24=Generate a self-signed Trusted Certificate.\n\
+[-alias ALIAS] [-sigalg ALGORITHM] [-dname NAME]\n\
+[-validity DAY_COUNT] [-keypass PASSWORD]\n\
+[-storetype STORE_TYPE] [-keystore URL]\n\
+[-storepass PASSWORD] [-provider PROVIDER_CLASS_NAME] [-v].
+Main.25=NOT IMPLEMENTED YET. Import JDK1.1 Identity Database.\n\
+[-file FILE] [-storetype STORE_TYPE] [-keystore URL]\n\
+[-storepass PASSWORD] [-provider PROVIDER_CLASS_NAME] [-v].
+Main.26=Issue a Certificate Signing Request (CSR).\n\
+[-alias ALIAS] [-sigalg ALGORITHM] [-file FILE]\n\
+[-keypass PASSWORD] [-storetype STORE_TYPE] [-keystore URL]\n\
+[-storepass PASSWORD] [-provider PROVIDER_CLASS_NAME] [-v]\n\
+[-attributes].
+Main.27=Export a Certificate from a key store.\n\
+[-alias ALIAS] [-file FILE] [-storetype STORE_TYPE]\n\
+[-keystore URL] [-storepass PASSWORD]\n\
+[-provider PROVIDER_CLASS_NAME] [-rfc] [-v].
+Main.28=Print one or all Certificates in a key store to STDOUT.\n\
+[-alias ALIAS] [-storetype STORE_TYPE] [-keystore URL]\n\
+[-storepass PASSWORD] [-provider PROVIDER_CLASS_NAME] [-rfc] [-v].
+Main.29=Print a human-readable form of a Certificate in a FILE.\n\
+[-file FILE] [-v].
+Main.30=Clone a Key Entry in a key store.\n\
+[-alias ALIAS] [-dest ALIAS] [-keypass PASSWORD]\n\
+[-new PASSWORD] [-storetype STORE_TYPE] [-keystore URL]\n\
+[-storepass PASSWORD] [-provider PROVIDER_CLASS_NAME] [-v].
+Main.31=Change the password protecting a key store.\n\
+[-new PASSWORD] [-storetype STORE_TYPE] [-keystore URL]\n\
+[-storepass PASSWORD] [-provider PROVIDER_CLASS_NAME] [-v].
+Main.32=Change the password protecting a Key Entry in a key store.\n\
+[-alias ALIAS] [-keypass PASSWORD] [-new PASSWORD]\n\
+[-storetype STORE_TYPE] [-keystore URL]\n\
+[-storepass PASSWORD] [-provider PROVIDER_CLASS_NAME] [-v].
+Main.33=Delete a Key Entry or a Trusted Certificate from a key store.\n\
+[-alias ALIAS] [-storetype STORE_TYPE] [-keystore URL]\n\
+[-storepass PASSWORD] [-provider PROVIDER_CLASS_NAME] [-v].
+
+Command.19=Failed creating new file at {0}
+Command.20=Unable to find a suitable signature algorithm named {0}, although we found a key-pair generation algorithm named {1}
+Command.21=Enter key password for <{0}>:
+Command.23=A correct key password MUST be provided
+Command.24=Enter key store password:
+#Command.36=Option '-keystore' is undefined, or is an empty string, and 'user.home' is unknown
+Command.36=Unable to locate a valid key store
+Command.40=Provider fully qualified class name:
+Command.42=File object [{0}] exists but is NOT a file
+Command.44=File [{0}] exists but is NOT writable
+Command.46=File object [{0}] MUST be an existing readable file
+Command.48=Signature algorithm is missing and private key is of unknown or unsupported type
+Command.51=Validity period MUST be greater than zero
+Command.52=Unable to get signature algorithm name
+Command.60=Unknown or unsupported signature algorithm: {0}
+Command.63=Saving key store at {0}
+Command.66=Owner: {0}
+Command.67=Issuer: {0}
+Command.68=Serial number: {0,number}
+Command.69=Valid from: {0,date,full} - {0,time,full}
+Command.70=\ \ \ \ \ until: {0,date,full} - {0,time,full}
+Command.71=Certificate fingerprints
+Command.72=\ \ \ \ \ \ MD5: {0}
+Command.73=\ \ SHA-160: {0}
+Command.75=Alias [{0}] MUST be knwon to the key store
+Command.77=Alias [{0}] MUST be associated with a Key Entry
+
+CertReqCmd.27=Certification request stored in {0}
+CertReqCmd.28=Submit this to your CA
+CertReqCmd.25=Usage: keytool -certreq [OPTION]...\n\
+Generate a PKCS#10 Certificate Signing Request (CSR) and write it to a \
+designated output destination.\n\n\
+IMPORTANT: Some documentation claims that the Attributes field, in the CSR is \
+OPTIONAL while RFC-2986 implies the opposite. This implementation considers \
+this field, by default, as OPTIONAL, unless option -attributes is specified.
+CertReqCmd.24=Please report bugs at http://www.gnu.org/software/classpath/bugs.html
+CertReqCmd.23=Command options
+CertReqCmd.22=Alias of an entry in the key store on whose behalf the CSR is \
+generated. The value "mykey" (all lower case, without the enclosing quotes) \
+is used when this option is omitted.
+CertReqCmd.21=ALIAS
+CertReqCmd.20=Name of the digital signature algorithm to use for signing the \
+certificate. If omitted, a default value is chosen based on the type of the \
+private key associated with ALIAS. If the key is a "DSA" one, the value for \
+signature algorithm will be "SHA1withDSA". If on the other hand the key is \
+an "RSA" one, then "MD5withRSA" will be the signature algorithm.
+CertReqCmd.19=ALGORITHM
+CertReqCmd.18=Destination of the generated CSR. STDOUT is used if this \
+option is omitted.
+CertReqCmd.17=FILE
+CertReqCmd.16=Password to unlock the Key Entry associated with ALIAS. If \
+omitted, the tool will attempt to unlock the Key Entry using the same password \
+protecting the key store. If this fails, you will be prompted for a password.
+CertReqCmd.14=Type of the key store to use. If omitted, the default value is \
+that of the property "keystore.type" in the security properties file.
+CertReqCmd.13=STORE_TYPE
+CertReqCmd.12=Location of the key store to use. The default value is a \
+file-based scheme whose path is the file named ".keystore" in your home \
+directory.\n\
+If URL is malformed, the tool will use URL as a file-name of a key store; \
+i.e. as if the protocol was "file:".
+CertReqCmd.11=URL
+CertReqCmd.10=Password to unlock the key store. If omitted, you will be \
+prompted for one.
+CertReqCmd.9=PASSWORD
+CertReqCmd.8=Fully qualified class name of a Security Provider to add to the \
+JVM in-use.
+CertReqCmd.7=PROVIDER_CLASS_NAME
+CertReqCmd.6=Emit more verbose messages.
+CertReqCmd.5=Force the tool to encode a NULL DER value in the CSR as the value \
+of the Attributes field.
+
+DeleteCmd.19=Enter the Alias to delete:
+DeleteCmd.18=Usage: keytool -delete [OPTION]...\n\
+Delete a designated key store entry.
+DeleteCmd.17=Please report bugs at http://www.gnu.org/software/classpath/bugs.html
+DeleteCmd.16=Command options
+DeleteCmd.15=Alias of an entry to delete. The value "mykey" (all lower case, \
+without the enclosing quotes) is used when this option is omitted.
+DeleteCmd.14=ALIAS
+DeleteCmd.13=Type of the key store to use. If omitted, the default value is \
+that of the property "keystore.type" in the security properties file.
+DeleteCmd.12=STORE_TYPE
+DeleteCmd.11=Location of the key store to use. The default value is a \
+file-based scheme whose path is the file named ".keystore" in your home \
+directory.\n\
+If URL is malformed, the tool will use URL as a file-name of a key store; \
+i.e. as if the protocol was "file:".
+DeleteCmd.10=URL
+DeleteCmd.20=Alias MUST NOT be null or an empty string
+DeleteCmd.9=Password to unlock the key store. If omitted, you will be \
+prompted for one.
+DeleteCmd.8=PASSWORD
+DeleteCmd.7=Fully qualified class name of a Security Provider to add to the \
+JVM in-use.
+DeleteCmd.6=PROVIDER_CLASS_NAME
+DeleteCmd.5=Emit more verbose messages.
+
+GenKeyCmd.0=\nYou are about to enter information that will be incorporated into\n\
+your certificate request. This information is what is called a\n\
+Distinguished Name or DN. There are quite a few fields but you\n\
+can use supplied default values, displayed between brackets, by just\n\
+hitting <Enter>, or blank the field by entering the <.> character\n\
+before hitting <Enter>.\n\n
+GenKeyCmd.6=The Sample Company
+GenKeyCmd.7=Sydney
+GenKeyCmd.8=NSW
+GenKeyCmd.9=AU
+GenKeyCmd.10=Common Name (hostname, IP, or your name):
+GenKeyCmd.11=Organization Name (company) [{0}]:
+GenKeyCmd.13=Organizational Unit Name (department, division):
+GenKeyCmd.14=Locality Name (city, district) [{0}]:
+GenKeyCmd.16=State or Province Name (full name) [{0}]:
+GenKeyCmd.18=Country Name (2 letter code) [{0}]:
+GenKeyCmd.54=Key size MUST be greater than zero
+GenKeyCmd.57=Usage: keytool -genkey [OPTION]...\n\
+Generate a new key-pair and save these credentials in the key store as a Key \
+Entry, associated with a designated Alias.
+GenKeyCmd.58=Please report bugs at http://www.gnu.org/software/classpath/bugs.html
+GenKeyCmd.59=Command options
+GenKeyCmd.60=Alias of the Key Entry to generate. The value "mykey" (all lower \
+case, without the enclosing quotes) is used when this option is omitted.
+GenKeyCmd.61=ALIAS
+GenKeyCmd.62=Name of the key-pair generation algorithm. The default value is \
+"DSS" (a synonym for the Digital Signature Algorithm also known as DSA).
+GenKeyCmd.63=ALGORITHM
+GenKeyCmd.64=Number of bits of the shared modulus, for both the public and \
+private keys, to use for the new keys. If omitted, 1024 is used.
+GenKeyCmd.65=SIZE
+GenKeyCmd.66=Name of the digital signature algorithm to use for signing the \
+certificate. If omitted, a default value is chosen based on the type of the \
+private key associated with ALIAS. If the key is a "DSA" one, the value for \
+signature algorithm will be "SHA1withDSA". If on the other hand the key is \
+an "RSA" one, then "MD5withRSA" will be the signature algorithm.
+GenKeyCmd.68=The X.500 Distinguished Name of the Subject of the generated \
+certificate. If omitted you will be prompted for one.
+GenKeyCmd.69=NAME
+GenKeyCmd.70=Password to protect the newly created Key Entry. If omitted, \
+you will be prompted to provide a password.
+GenKeyCmd.71=PASSWORD
+GenKeyCmd.72=Number of days the generated certificate is valid for. If \
+omitted, 90 is used.
+GenKeyCmd.73=DAY_COUNT
+GenKeyCmd.74=Type of the key store to use. If omitted, the default value is \
+that of the property "keystore.type" in the security properties file.
+GenKeyCmd.75=STORE_TYPE
+GenKeyCmd.76=Location of the key store to use. The default value is a \
+file-based scheme whose path is the file named ".keystore" in your home \
+directory.\n\
+If URL is malformed, the tool will use URL as a file-name of a key store; \
+i.e. as if the protocol was "file:".
+GenKeyCmd.77=URL
+GenKeyCmd.78=Password to unlock the key store. If omitted, you will be \
+prompted for one.
+GenKeyCmd.80=Fully qualified class name of a Security Provider to add to the \
+JVM in-use.
+GenKeyCmd.81=PROVIDER_CLASS_NAME
+GenKeyCmd.82=Emit more verbose messages.
+
+StorePasswdCmd.19=Too many failed attempts
+StorePasswdCmd.18=Usage: keytool -storepasswd [OPTION]...\n\
+Change the password protecting a key store.
+StorePasswdCmd.17=Please report bugs at http://www.gnu.org/software/classpath/bugs.html
+StorePasswdCmd.16=Command options
+StorePasswdCmd.15=The new, and different, password to protect the key store. \
+If omitted, you will be prompted for one.
+StorePasswdCmd.13=Type of the key store to use. If omitted, the default value is \
+that of the property "keystore.type" in the security properties file.
+StorePasswdCmd.12=STORE_TYPE
+StorePasswdCmd.11=Location of the key store to use. The default value is a \
+file-based scheme whose path is the file named ".keystore" in your home \
+directory.\n\
+If URL is malformed, the tool will use URL as a file-name of a key store; \
+i.e. as if the protocol was "file:".
+StorePasswdCmd.10=URL
+StorePasswdCmd.20=Enter new key store password:
+StorePasswdCmd.21=Password MUST be at least 6 characters.
+StorePasswdCmd.22=New password MUST be different than the old one.
+StorePasswdCmd.23=Re-enter new key store password:
+StorePasswdCmd.24=Passwords MUST be the same in both attempts.
+StorePasswdCmd.9=Password to unlock the key store. If omitted, you will be \
+prompted for one.
+StorePasswdCmd.8=PASSWORD
+StorePasswdCmd.7=Fully qualified class name of a Security Provider to add to the \
+JVM in-use.
+StorePasswdCmd.6=PROVIDER_CLASS_NAME
+StorePasswdCmd.5=Emit more verbose messages.
+
+KeyPasswdCmd.24=Enter new key password for <{0}>:
+KeyPasswdCmd.28=Re-enter new key password for <{0}>:
+KeyPasswdCmd.23=Usage: keytool -keypasswd [OPTION]...\n\
+Change the password protecting a Key Entry.
+KeyPasswdCmd.22=Please report bugs at http://www.gnu.org/software/classpath/bugs.html
+KeyPasswdCmd.21=Command options
+KeyPasswdCmd.20=The Alias which password is to be changed.
+KeyPasswdCmd.19=ALIAS
+KeyPasswdCmd.18=Password to unlock ALIAS. If omitted, the tool will attempt \
+to unlock the Key Entry using the same password protecting the key store. If \
+this fails, you will be prompted for a password.
+KeyPasswdCmd.16=The new, and different, password to protect ALIAS.
+KeyPasswdCmd.14=Type of the key store to use. If omitted, the default value is \
+that of the property "keystore.type" in the security properties file.
+KeyPasswdCmd.13=STORE_TYPE
+KeyPasswdCmd.12=Location of the key store to use. The default value is a \
+file-based scheme whose path is the file named ".keystore" in your home \
+directory.\n\
+If URL is malformed, the tool will use URL as a file-name of a key store; \
+i.e. as if the protocol was "file:".
+KeyPasswdCmd.11=URL
+KeyPasswdCmd.10=Password to unlock the key store. If omitted, you will be \
+prompted for one.
+KeyPasswdCmd.9=PASSWORD
+KeyPasswdCmd.8=Fully qualified class name of a Security Provider to add to the \
+JVM in-use.
+KeyPasswdCmd.7=PROVIDER_CLASS_NAME
+KeyPasswdCmd.6=Emit more verbose messages.
+
+KeyCloneCmd.23=Destination Alias MUST NOT exist in key store
+KeyCloneCmd.26=Enter destination alias:
+KeyCloneCmd.27=Destination alias MUST NOT be null nor empty
+KeyCloneCmd.28=Enter new key password for <{0}> [{1}]:
+KeyCloneCmd.22=Usage: keytool -keyclone [OPTION]...\n\
+Clone an existing Key Entry and store it under a new (different) Alias \
+protecting its private key material with possibly a new password.
+KeyCloneCmd.21=Please report bugs at http://www.gnu.org/software/classpath/bugs.html
+KeyCloneCmd.20=Command options
+KeyCloneCmd.19=Alias of an entry to clone. The value "mykey" (all lower case, \
+without the enclosing quotes) is used when this option is omitted.
+KeyCloneCmd.17=Alias to identify the cloned copy of the Key Entry.
+KeyCloneCmd.16=ALIAS
+KeyCloneCmd.15=Password to unlock the Key Entry associated with the Alias to \
+clone. If omitted, the tool will attempt to unlock the Key Entry using the \
+same password protecting the key store. If this fails, you will be prompted \
+for a password.
+KeyCloneCmd.13=Password to protect the cloned copy of the Key Entry. If \
+omitted, you will be prompted to provide one.
+KeyCloneCmd.11=Type of the key store to use. If omitted, the default value is \
+that of the property "keystore.type" in the security properties file.
+KeyCloneCmd.10=STORE_TYPE
+KeyCloneCmd.9=Location of the key store to use. The default value is a \
+file-based scheme whose path is the file named ".keystore" in your home \
+directory.\n\
+If URL is malformed, the tool will use URL as a file-name of a key store; \
+i.e. as if the protocol was "file:".
+KeyCloneCmd.8=URL
+KeyCloneCmd.7=Password to unlock the key store. If omitted, you will be \
+prompted for one.
+KeyCloneCmd.6=PASSWORD
+KeyCloneCmd.5=Fully qualified class name of a Security Provider to add to the \
+JVM in-use.
+KeyCloneCmd.4=PROVIDER_CLASS_NAME
+KeyCloneCmd.3=Emit more verbose messages.
+
+ListCmd.21=Key store type: {0}
+ListCmd.22=Key store provider: {0}
+ListCmd.24=Key store contains {0,number} entry(ies)
+ListCmd.20=Usage: keytool -list [OPTION]...\n\
+Print one or all of the key store entries to STDOUT. Usually this command \
+will only print a fingerprint of the certificate, unless either -rfc or -v \
+is specified.
+ListCmd.30=Alias name: {0}
+ListCmd.31=Creation timestamp: {0,date,full} - {0,time,full}
+ListCmd.32=Entry type: trusted-certificate
+ListCmd.33=Entry type: key-entry
+ListCmd.34=Alias [{0}] is unknown to the key store
+ListCmd.38=Certificate chain length: {0,number}
+ListCmd.39=Certificate[1]:
+ListCmd.40=Certificate[{0,number}]:
+ListCmd.42=*******************************************
+ListCmd.43=-----BEGIN CERTIFICATE-----
+ListCmd.44=-----END CERTIFICATE-----
+ListCmd.45=Certificate fingerprint (MD5): {0}
+ListCmd.19=Please report bugs at http://www.gnu.org/software/classpath/bugs.html
+ListCmd.18=Command options
+ListCmd.17=Alias of an entry to list. If omitted, all entries are listed.
+ListCmd.16=ALIAS
+ListCmd.15=Type of the key store to use. If omitted, the default value is \
+that of the property "keystore.type" in the security properties file.
+ListCmd.14=STORE_TYPE
+ListCmd.13=Location of the key store to use. The default value is a \
+file-based scheme whose path is the file named ".keystore" in your home \
+directory.\n\
+If URL is malformed, the tool will use URL as a file-name of a key store; \
+i.e. as if the protocol was "file:".
+ListCmd.12=URL
+ListCmd.11=Password to unlock the key store. If omitted, you will be \
+prompted for one.
+ListCmd.10=PASSWORD
+ListCmd.9=Fully qualified class name of a Security Provider to add to the \
+JVM in-use.
+ListCmd.8=PROVIDER_CLASS_NAME
+ListCmd.7=Output the certificate in human-readable format, even if -rfc is \
+also specified.
+ListCmd.6=Use RFC-1421 specifications when encoding the output.
+
+ImportCmd.34=Failed to establish chain-of-trust from reply
+ImportCmd.37=Unable to find anchor certificate for {0}
+ImportCmd.38=Public keys, in key store and certificate, MUST be of the same type
+ImportCmd.32=Can this certificate be trusted?
+ImportCmd.40=Key entry associated with {0} has an unknown or unsupported public key type {1}
+ImportCmd.41=Public keys, in key store and certificate, MUST be the same
+ImportCmd.29=Certificate was added to the key store
+ImportCmd.28=Certificate was not added to the key store
+ImportCmd.27=Usage: keytool -import [OPTION]...\n\
+Read an X.509 certificate, or a PKCS#7 Certificate Reply from a designated \
+input source and incorporate the certificates into the key store.
+ImportCmd.26=Please report bugs at http://www.gnu.org/software/classpath/bugs.html
+ImportCmd.25=Command options
+ImportCmd.24=If ALIAS does not already exist in the key store, the tool treats \
+the certificate in FILE as a new Trusted Certificate.\n\
+If ALIAS exists in the key store, the tool will treat the certificate(s) in \
+FILE as a Certificate Reply (which can be a chain of certificates).
+ImportCmd.23=ALIAS
+ImportCmd.22=Location of the Certificate or Certificate Reply to import.
+ImportCmd.21=FILE
+ImportCmd.20=Password to protect the Key Entry associated with ALIAS. If \
+this option is omitted, and the chain-of-trust for the Certificate Reply has \
+been established, the tool will first attempt to unlock the Key Entry using \
+the same password protecting the key store. If this fails, you will be \
+prompted to provide a password.
+ImportCmd.19=PASSWORD
+ImportCmd.18=Prevent the tool from prompting the user.
+ImportCmd.17=Additionally use a key store, of type "JKS", named "cacerts", \
+and located in lib/security in an installed Java Runtime Environment, when \
+trying to establish chains-of-trust.
+ImportCmd.16=Type of the key store to use. If omitted, the default value is \
+that of the property "keystore.type" in the security properties file.
+ImportCmd.15=STORE_TYPE
+ImportCmd.14=Location of the key store to use. The default value is a \
+file-based scheme whose path is the file named ".keystore" in your home \
+directory.\n\
+If URL is malformed, the tool will use URL as a file-name of a key store; \
+i.e. as if the protocol was "file:".
+ImportCmd.13=URL
+ImportCmd.12=Password to unlock the key store. If omitted, you will be \
+prompted for one.
+ImportCmd.11=PASSWORD
+ImportCmd.10=Fully qualified class name of a Security Provider to add to the \
+JVM in-use.
+ImportCmd.9=PROVIDER_CLASS_NAME
+ImportCmd.8=Emit more verbose messages.
+ImportCmd.7=Was unable to build a certificate-chain. Only {0,number} out of {1,number} certificates were processed
+
+ExportCmd.17=Usage: keytool -export [OPTION]...\n\
+Export a certificate stored in the key store to a designated output \
+destination, either in binary format or in RFC-1421 compliant encoding.
+ExportCmd.18=Please report bugs at http://www.gnu.org/software/classpath/bugs.html
+ExportCmd.19=Command options
+ExportCmd.20=Alias of an entry to export. The value "mykey" (all lower case, \
+without the enclosing quotes) is used when this option is omitted.
+ExportCmd.21=ALIAS
+ExportCmd.22=Destination of the exported certificate. STDOUT is used if this \
+option is omitted.
+ExportCmd.23=FILE
+ExportCmd.24=Type of the key store to use. If omitted, the default value is \
+that of the property "keystore.type" in the security properties file.
+ExportCmd.25=STORE_TYPE
+ExportCmd.26=Location of the key store to use. The default value is a \
+file-based scheme whose path is the file named ".keystore" in your home \
+directory.\n\
+If URL is malformed, the tool will use URL as a file-name of a key store; \
+i.e. as if the protocol was "file:".
+ExportCmd.27=URL
+ExportCmd.28=Password to unlock the key store. If omitted, you will be \
+prompted for one.
+ExportCmd.29=PASSWORD
+ExportCmd.30=Fully qualified class name of a Security Provider to add to the \
+JVM in-use.
+ExportCmd.31=PROVIDER_CLASS_NAME
+ExportCmd.32=Use RFC-1421 specifications when encoding the output.
+ExportCmd.33=Output the certificate in binary DER encoding, which is the \
+default format. If -rfc is also present, this option is ignored.
+
+IdentityDBCmd.7=Usage: keytool -identitydb [OPTION]...\n\
+NOT IMPLEMENTED YET. Import a JDK 1.1 style Identity Database.
+IdentityDBCmd.8=Please report bugs at http://www.gnu.org/software/classpath/bugs.html
+IdentityDBCmd.9=Command options
+IdentityDBCmd.10=Location of the Identity Database to import. If omitted, \
+STDIN is used.
+IdentityDBCmd.11=FILE
+IdentityDBCmd.12=Type of the key store to use. If omitted, the default value is \
+that of the property "keystore.type" in the security properties file.
+IdentityDBCmd.13=STORE_TYPE
+IdentityDBCmd.14=Location of the key store to use. The default value is a \
+file-based scheme whose path is the file named ".keystore" in your home \
+directory.\n\
+If URL is malformed, the tool will use URL as a file-name of a key store; \
+i.e. as if the protocol was "file:".
+IdentityDBCmd.15=URL
+IdentityDBCmd.16=Password to unlock the key store. If omitted, you will be \
+prompted for one.
+IdentityDBCmd.17=PASSWORD
+IdentityDBCmd.18=Fully qualified class name of a Security Provider to add to the \
+JVM in-use.
+IdentityDBCmd.19=PROVIDER_CLASS_NAME
+IdentityDBCmd.20=Emit more verbose messages.
+
+PrintCertCmd.5=Usage: keytool -printcert [OPTION]...\n\
+Read a certificate from FILE and print it to STDOUT in a human-readable form.
+PrintCertCmd.6=Please report bugs at http://www.gnu.org/software/classpath/bugs.html
+PrintCertCmd.7=Command options
+PrintCertCmd.8=Location of the certificate to print. If omitted, STDIN is used.
+PrintCertCmd.9=FILE
+PrintCertCmd.10=Emit more verbose messages.
+
+SelfCertCmd.14=Usage: keytool -selfcert [OPTION]...\n\
+Generate a self-signed X.509 version 1 certificate.\n\n\
+The newly generated certificate will form a chain of one element which will \
+replace the previous chain associated with ALIAS.
+SelfCertCmd.15=Please report bugs at http://www.gnu.org/software/classpath/bugs.html
+SelfCertCmd.16=Command options
+SelfCertCmd.17=Alias of the Key Entry to select. The value "mykey" (all lower \
+case, without the enclosing quotes) is used when this option is omitted.
+SelfCertCmd.18=ALIAS
+SelfCertCmd.19=Name of the digital signature algorithm to use for signing the \
+certificate. If omitted, a default value is chosen based on the type of the \
+private key associated with ALIAS. If the key is a "DSA" one, the value for \
+signature algorithm will be "SHA1withDSA". If on the other hand the key is \
+an "RSA" one, then "MD5withRSA" will be the signature algorithm.
+SelfCertCmd.20=ALGORITHM
+SelfCertCmd.21=The X.500 Distinguished Name of the Subject of the generated \
+certificate. If omitted the Distinguished Name of the base certificate in \
+the chain associated with ALIAS is used instead.
+SelfCertCmd.22=NAME
+SelfCertCmd.23=Password to unlock the Key Entry associated with ALIAS. If \
+omitted, the tool will attempt to unlock the Key Entry using the same password \
+protecting the key store. If this fails, you will be prompted for a password.
+SelfCertCmd.24=PASSWORD
+SelfCertCmd.25=Number of days the generated certificate is valid for. If \
+omitted, 90 is used.
+SelfCertCmd.26=DAY_COUNT
+SelfCertCmd.27=Type of the key store to use. If omitted, the default value is \
+that of the property "keystore.type" in the security properties file.
+SelfCertCmd.28=STORE_TYPE
+SelfCertCmd.29=Location of the key store to use. The default value is a \
+file-based scheme whose path is the file named ".keystore" in your home \
+directory.\n\
+If URL is malformed, the tool will use URL as a file-name of a key store; \
+i.e. as if the protocol was "file:".
+SelfCertCmd.30=URL
+SelfCertCmd.31=Password to unlock the key store. If omitted, you will be \
+prompted for one.
+SelfCertCmd.32=PASSWORD
+SelfCertCmd.33=Fully qualified class name of a Security Provider to add to the \
+JVM in-use.
+SelfCertCmd.34=PROVIDER_CLASS_NAME
+SelfCertCmd.35=Emit more verbose messages.
diff --git a/resource/gnu/classpath/tools/native2ascii/messages.properties b/resource/gnu/classpath/tools/native2ascii/messages.properties
new file mode 100644
index 000000000..ab860c8d2
--- /dev/null
+++ b/resource/gnu/classpath/tools/native2ascii/messages.properties
@@ -0,0 +1,43 @@
+# messages.properties -- English language messages
+# 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.
+
+Native2ASCII.TooManyFiles=too many files specified
+Native2ASCII.Usage=Usage: native2ascii [OPTIONS]... [INPUTFILE [OUTPUTFILE]]
+Native2ASCII.EncodingHelp=encoding to use
+Native2ASCII.EncodingArgName=NAME
+Native2ASCII.EncodingSpecified=encoding already specified
+Native2ASCII.ReversedHelp=convert from encoding to native
diff --git a/resource/gnu/classpath/tools/serialver/messages.properties b/resource/gnu/classpath/tools/serialver/messages.properties
new file mode 100644
index 000000000..8900795d4
--- /dev/null
+++ b/resource/gnu/classpath/tools/serialver/messages.properties
@@ -0,0 +1,44 @@
+# messages.properties -- English language messages
+# 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.
+
+SerialVer.NoClassesSpecd=no classes specified
+SerialVer.HelpHeader=serialver [OPTIONS]... CLASS...\n\nPrint the serialVersionUID of the specified classes
+SerialVer.5=classpath
+SerialVer.ClasspathHelp=class path to use to find classes
+SerialVer.ClassNotSerial=serialver: class {0} is not serializable
+SerialVer.ClassNotFound=serialver: class {0} not found
+SerialVer.DupClasspath=classpath already specified
diff --git a/scripts/check_jni_methods.sh b/scripts/check_jni_methods.sh
index 243bb7e4a..999e143ec 100755
--- a/scripts/check_jni_methods.sh
+++ b/scripts/check_jni_methods.sh
@@ -29,7 +29,7 @@ find native/jni -name \*.cpp | \
cut -f4 -d\ | \
LC_ALL=C sed -e 's,^\JNIEXPORT .* JNICALL \(Java_[a-z_A-Z0-9]*\) *(.*$,\1,' >> $TMPFILE2
mv $TMPFILE2 $TMPFILE3
-sort $TMPFILE3 > $TMPFILE2
+sort $TMPFILE3 | uniq > $TMPFILE2
rm $TMPFILE3
# Write temporary ignore file.
diff --git a/tools/.cvsignore b/tools/.cvsignore
index 75730de04..cf3688511 100644
--- a/tools/.cvsignore
+++ b/tools/.cvsignore
@@ -3,3 +3,4 @@ keytool
Makefile.in
Makefile
tools.zip
+appletviewer
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 7a8f1ce97..201939832 100755
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -21,8 +21,46 @@ endif
endif
endif
-bin_SCRIPTS = jarsigner keytool
-EXTRA_DIST = jarsigner.in keytool.in
+if CREATE_WRAPPERS
+bin_SCRIPTS =
+bin_PROGRAMS = appletviewer jarsigner keytool
+
+if FOUND_GCJ
+LIBJVM = -lgcj
+else
+if FOUND_CACAO
+LIBJVM = -ljvm
+else
+LIBJVM =
+endif
+endif
+
+appletviewer_SOURCES = toolwrapper.c
+appletviewer_CFLAGS = -Wall \
+ -DDATA_DIR="\"$(datadir)\"" \
+ -DPACKAGE="\"$(PACKAGE)\"" \
+ -DTOOLNAME="\"appletviewer\""
+appletviewer_LDFLAGS = -L$(libdir) $(LIBJVM)
+
+jarsigner_SOURCES = toolwrapper.c
+jarsigner_CFLAGS = -Wall \
+ -DDATA_DIR="\"$(datadir)\"" \
+ -DPACKAGE="\"$(PACKAGE)\"" \
+ -DTOOLNAME="\"jarsigner\""
+jarsigner_LDFLAGS = -L$(libdir) $(LIBJVM)
+
+keytool_SOURCES = toolwrapper.c
+keytool_CFLAGS = -Wall \
+ -DDATA_DIR="\"$(datadir)\"" \
+ -DPACKAGE="\"$(PACKAGE)\"" \
+ -DTOOLNAME="\"keytool\""
+keytool_LDFLAGS = -L$(libdir) $(LIBJVM)
+
+else
+bin_SCRIPTS = appletviewer jarsigner keytool
+bin_PROGRAMS =
+endif
+EXTRA_DIST = toolwrapper.c appletviewer.in jarsigner.in keytool.in
# All our example java source files
TOOLS_JAVA_FILES = $(srcdir)/gnu/classpath/tools/*.java $(srcdir)/gnu/classpath/tools/*/*.java $(srcdir)/gnu/classpath/tools/*/*/*.java
@@ -43,10 +81,8 @@ TOOLS_TEMPLATES = $(GRMIC_TEMPLATES) $(RMIC_TEMPLATES)
# This covers the built-in help texts, both for giop and rmic subpackages.
GIOP_HELPS = $(srcdir)/gnu/classpath/tools/giop/*.txt
RMI_HELPS = $(srcdir)/gnu/classpath/tools/rmi/*.txt
-JARSIGNER_HELPS = $(srcdir)/gnu/classpath/tools/jarsigner/*.txt
-KEYTOOL_HELPS = $(srcdir)/gnu/classpath/tools/keytool/*.txt
-TOOLS_HELPS = $(GIOP_HELPS) $(RMI_HELPS) $(JARSIGNER_HELPS) $(KEYTOOL_HELPS)
+TOOLS_HELPS = $(GIOP_HELPS) $(RMI_HELPS)
# The tool specific README files.
READMES = $(srcdir)/gnu/classpath/tools/giop/README
@@ -81,14 +117,13 @@ dist-hook:
$(TOOLS_ZIP): $(TOOLS_JAVA_FILES)
mkdir -p classes/gnu/classpath/tools/giop/grmic/templates
mkdir -p classes/gnu/classpath/tools/rmi/rmic/templates
+ mkdir -p classes/gnu/classpath/tools/appletviewer
mkdir -p classes/gnu/classpath/tools/jarsigner
mkdir -p classes/gnu/classpath/tools/keytool
cp $(RMIC_TEMPLATES) classes/gnu/classpath/tools/rmi/rmic/templates
cp $(GRMIC_TEMPLATES) classes/gnu/classpath/tools/giop/grmic/templates
cp $(RMI_HELPS) classes/gnu/classpath/tools/rmi/
cp $(GIOP_HELPS) classes/gnu/classpath/tools/giop/
- cp $(JARSIGNER_HELPS) classes/gnu/classpath/tools/jarsigner/
- cp $(KEYTOOL_HELPS) classes/gnu/classpath/tools/keytool/
$(JCOMPILER) -d classes $(TOOLS_JAVA_FILES)
(cd classes; \
if test "$(ZIP)" != ""; then $(ZIP) -r ../$(TOOLS_ZIP) .; fi; \
@@ -99,3 +134,7 @@ $(TOOLS_ZIP): $(TOOLS_JAVA_FILES)
# Zip file be gone! (and make sure the classes are gone too)
clean-local:
rm -rf $(TOOLS_ZIP) classes
+
+# FIXME: remove this when GNU Classpath includes a bootstrap VM.
+installcheck-binSCRIPTS:
+ :
diff --git a/tools/appletviewer.in b/tools/appletviewer.in
index 61571d906..81e39ad91 100644
--- a/tools/appletviewer.in
+++ b/tools/appletviewer.in
@@ -36,7 +36,6 @@
## obligated to do so. If you do not wish to do so, delete this
## exception statement from your version.
##
-##
## A simple shell script to launch the GNU Classpath appletviewer tool.
##
@@ -44,20 +43,4 @@ prefix=@prefix@
tools_dir=@datadir@/@PACKAGE@
tools_cp=${tools_dir}/tools.zip
-# find the java executable...
-if [ -z "${JAVA}" ] ; then
- if [ -n "${JAVA_HOME}" ] ; then
- if [ -x "${JAVA_HOME}/jre/sh/java" ] ; then
- JAVA="${JAVA_HOME}/jre/sh/java"
- else
- JAVA="${JAVA_HOME}/bin/java"
- fi
- else
- JAVA=`which java 2> /dev/null `
- if [ -z "${JAVA}" ] ; then
- JAVA=java
- fi
- fi
-fi
-
-exec "${JAVA}" -Xbootclasspath/p:"${tools_cp}" gnu.classpath.tools.appletviewer.Main $@
+exec @VM_BINARY@ -Xbootclasspath/p:"${tools_cp}" gnu.classpath.tools.appletviewer.Main $@
diff --git a/tools/gnu/classpath/tools/appletviewer/AppletTag.java b/tools/gnu/classpath/tools/appletviewer/AppletTag.java
index b2d7ccb2b..80d572857 100644
--- a/tools/gnu/classpath/tools/appletviewer/AppletTag.java
+++ b/tools/gnu/classpath/tools/appletviewer/AppletTag.java
@@ -451,15 +451,19 @@ class AppletTag
else
{
String dirname = documentbase.getFile();
-
- // Determine dirname for file by stripping everything
- // past the last file separator.
- dirname = dirname.substring(0,
- dirname.lastIndexOf(File.separatorChar) + 1);
-
- fullcodebase = new URL(documentbase.getProtocol(),
- documentbase.getHost(),
- documentbase.getPort(), dirname);
+ if (dirname.indexOf(".") < 0)
+ fullcodebase = new URL(documentbase + File.separator);
+ else
+ {
+ // Determine dirname for file by stripping everything
+ // past the last file separator.
+ dirname = dirname.substring(0,
+ dirname.lastIndexOf(File.separatorChar) + 1);
+
+ fullcodebase = new URL(documentbase.getProtocol(),
+ documentbase.getHost(),
+ documentbase.getPort(), dirname);
+ }
}
}
else
diff --git a/tools/gnu/classpath/tools/appletviewer/Main.java b/tools/gnu/classpath/tools/appletviewer/Main.java
index 878b2be8a..1d9fed2b0 100644
--- a/tools/gnu/classpath/tools/appletviewer/Main.java
+++ b/tools/gnu/classpath/tools/appletviewer/Main.java
@@ -125,118 +125,108 @@ class Main
public static void main(String[] args) throws IOException
{
parser = new ClasspathToolParser("appletviewer", true);
- parser.setHeader("usage: appletviewer [OPTION] --code=FILE | URL...");
-
+ parser.setHeader("usage: appletviewer [OPTION] -code CODE | URL...");
+
OptionGroup attributeGroup = new OptionGroup("Applet tag options");
attributeGroup.add(new Option("code", Main.messages.getString
("gcjwebplugin.code_description"),
- "<code attribute>")
- {
- public void parsed(String argument) throws OptionException
- {
- code = argument;
- }
- });
+ "CODE")
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ code = argument;
+ }
+ });
attributeGroup.add(new Option("codebase", Main.messages.getString
- ("gcjwebplugin.codebase_description"),
- "<codebase attribute>")
- {
- public void parsed(String argument) throws OptionException
- {
- codebase = argument;
- }
- });
+ ("gcjwebplugin.codebase_description"),
+ "CODEBASE")
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ codebase = argument;
+ }
+ });
attributeGroup.add(new Option("archive", Main.messages.getString
- ("gcjwebplugin.archive_description"),
- "<archive attribute>")
- {
- public void parsed(String argument) throws OptionException
- {
- archive = argument;
- }
- });
+ ("gcjwebplugin.archive_description"),
+ "ARCHIVE")
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ archive = argument;
+ }
+ });
attributeGroup.add(new Option("width", Main.messages.getString
- ("gcjwebplugin.width_description"),
- "<width attribute>")
- {
- public void parsed(String argument) throws OptionException
- {
- dimensions.width = Integer.parseInt(argument);
- }
- });
+ ("gcjwebplugin.width_description"),
+ "WIDTH")
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ dimensions.width = Integer.parseInt(argument);
+ }
+ });
attributeGroup.add(new Option("height", Main.messages.getString
- ("gcjwebplugin.height_description"),
- "<height attribute>")
- {
- public void parsed(String argument) throws OptionException
- {
- dimensions.height = Integer.parseInt(argument);
- }
- });
+ ("gcjwebplugin.height_description"),
+ "HEIGHT")
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ dimensions.height = Integer.parseInt(argument);
+ }
+ });
attributeGroup.add(new Option("param", Main.messages.getString
- ("gcjwebplugin.param_description"),
- "<name>,<value>")
- {
- public void parsed(String argument) throws OptionException
- {
- parameters.add(argument);
- }
- });
+ ("gcjwebplugin.param_description"),
+ "NAME,VALUE")
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ parameters.add(argument);
+ }
+ });
OptionGroup pluginGroup = new OptionGroup("Plugin option");
pluginGroup.add(new Option("plugin", Main.messages.getString
- ("gcjwebplugin.plugin_description"),
- "<input pipe>,<output pipe>")
- {
- public void parsed(String argument) throws OptionException
- {
- pluginMode = true;
- int comma = argument.indexOf(',');
- pipeInName = argument.substring(0, comma);
- pipeOutName = argument.substring(comma + 1);
- }
- });
+ ("gcjwebplugin.plugin_description"),
+ "INPUT,OUTPUT")
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ pluginMode = true;
+ int comma = argument.indexOf(',');
+ pipeInName = argument.substring(0, comma);
+ pipeOutName = argument.substring(comma + 1);
+ }
+ });
OptionGroup debuggingGroup = new OptionGroup("Debugging option");
- debuggingGroup.add(new Option ("verbose", Main.messages.getString
- ("gcjwebplugin.verbose_description"),
- null)
- {
- public void parsed(String argument) throws OptionException
- {
- verbose = true;
- }
- });
+ debuggingGroup.add(new Option("verbose", Main.messages.getString
+ ("gcjwebplugin.verbose_description"),
+ (String) null)
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ verbose = true;
+ }
+ });
OptionGroup compatibilityGroup = new OptionGroup("Compatibility options");
compatibilityGroup.add(new Option("debug", Main.messages.getString
("gcjwebplugin.debug_description"),
- null)
- {
- public void parsed(String argument) throws OptionException
- {
- // Currently ignored.
- }
- });
+ (String) null)
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ // Currently ignored.
+ }
+ });
compatibilityGroup.add(new Option("encoding", Main.messages.getString
("gcjwebplugin.encoding_description"),
- "<character set>")
- {
- public void parsed(String argument) throws OptionException
- {
- // FIXME: We should probably be using
- // java.nio.charset.CharsetDecoder to handle the encoding. What
- // is the status of Classpath's implementation?
- }
- });
- compatibilityGroup.add(new Option('J', Main.messages.getString
- ("gcjwebplugin.j_description"),
- "<virtual machine option>")
- {
- public void parsed(String argument) throws OptionException
- {
- // -J should be handled by the appletviewer wrapper binary.
- // We add it here so that it shows up in the --help output.
- }
- });
+ "CHARSET")
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ // FIXME: We should probably be using
+ // java.nio.charset.CharsetDecoder to handle the encoding. What
+ // is the status of Classpath's implementation?
+ }
+ });
parser.add(attributeGroup);
parser.add(pluginGroup);
parser.add(debuggingGroup);
diff --git a/tools/gnu/classpath/tools/getopt/ClasspathToolParser.java b/tools/gnu/classpath/tools/getopt/ClasspathToolParser.java
index be382a7a4..e712056ef 100644
--- a/tools/gnu/classpath/tools/getopt/ClasspathToolParser.java
+++ b/tools/gnu/classpath/tools/getopt/ClasspathToolParser.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package gnu.classpath.tools.getopt;
+import java.text.MessageFormat;
+
import gnu.classpath.Configuration;
/**
@@ -50,13 +52,13 @@ public class ClasspathToolParser
{
private static String getVersionString(String programName)
{
- return (programName + " (GNU Classpath) "
- + Configuration.CLASSPATH_VERSION
- + "\n\n"
- + "Copyright 2006 Free Software Foundation, Inc.\n"
- + "This is free software; see the source for copying conditions. There is NO\n"
- + "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.");
-
+ String fmt = (Messages.getString("ClasspathToolParser.VersionFormat")); //$NON-NLS-1$
+ return MessageFormat.format(fmt,
+ new Object[]
+ {
+ programName,
+ Configuration.CLASSPATH_VERSION
+ });
}
public ClasspathToolParser(String programName)
diff --git a/tools/gnu/classpath/tools/getopt/FileArgumentCallback.java b/tools/gnu/classpath/tools/getopt/FileArgumentCallback.java
index 0c44745c9..455389127 100644
--- a/tools/gnu/classpath/tools/getopt/FileArgumentCallback.java
+++ b/tools/gnu/classpath/tools/getopt/FileArgumentCallback.java
@@ -57,5 +57,6 @@ public abstract class FileArgumentCallback
*
* @param fileArgument the file name
*/
- public abstract void notifyFile(String fileArgument);
+ public abstract void notifyFile(String fileArgument)
+ throws OptionException;
}
diff --git a/tools/gnu/classpath/tools/getopt/Messages.java b/tools/gnu/classpath/tools/getopt/Messages.java
new file mode 100644
index 000000000..3c963d786
--- /dev/null
+++ b/tools/gnu/classpath/tools/getopt/Messages.java
@@ -0,0 +1,67 @@
+/* Messages.java -- i18n support for getopt
+ 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.getopt;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class Messages
+{
+ private static final String BUNDLE_NAME
+ = "gnu.classpath.tools.getopt.Messages"; //$NON-NLS-1$
+
+ private static final ResourceBundle RESOURCE_BUNDLE
+ = ResourceBundle.getBundle(BUNDLE_NAME);
+
+ private Messages()
+ {
+ }
+
+ public static String getString(String key)
+ {
+ try
+ {
+ return RESOURCE_BUNDLE.getString(key);
+ }
+ catch (MissingResourceException e)
+ {
+ return '!' + key + '!';
+ }
+ }
+}
diff --git a/tools/gnu/classpath/tools/getopt/Option.java b/tools/gnu/classpath/tools/getopt/Option.java
index e54aaa103..6f775e4a1 100644
--- a/tools/gnu/classpath/tools/getopt/Option.java
+++ b/tools/gnu/classpath/tools/getopt/Option.java
@@ -184,7 +184,6 @@ public abstract class Option
*/
public String getDescription()
{
- // FIXME: localization.
return description;
}
diff --git a/tools/gnu/classpath/tools/getopt/OptionGroup.java b/tools/gnu/classpath/tools/getopt/OptionGroup.java
index d83b273ba..f7d966d94 100644
--- a/tools/gnu/classpath/tools/getopt/OptionGroup.java
+++ b/tools/gnu/classpath/tools/getopt/OptionGroup.java
@@ -39,8 +39,10 @@
package gnu.classpath.tools.getopt;
import java.io.PrintStream;
+import java.text.BreakIterator;
import java.util.ArrayList;
import java.util.Iterator;
+import java.util.Locale;
/**
* An option group holds a collection of Options. It also has a name. Option
@@ -48,6 +50,9 @@ import java.util.Iterator;
*/
public class OptionGroup
{
+ /** An 80-character string of whitespaces to use as a source for padding. */
+ private static final String FILLER = " "
+ + " ";
private String name;
ArrayList options = new ArrayList();
@@ -70,6 +75,85 @@ public class OptionGroup
}
/**
+ * Print a designated text to a {@link PrintStream}, eventually wrapping the
+ * lines of text so as to ensure that the width of each line does not overflow
+ * {@link Parser#MAX_LINE_LENGTH} columns. The line-wrapping is done with a
+ * {@link BreakIterator} using the default {@link Locale}.
+ * <p>
+ * The text to print may contain <code>\n</code> characters. This method will
+ * force a line-break for each such character.
+ *
+ * @param out the {@link PrintStream} destination of the formatted text.
+ * @param text the text to print.
+ * @param leftMargin a positive value indicating the column position of the
+ * start of the first line. Continuation lines, if they exist, are
+ * printed starting at <code>leftMargin + 2</code> as per GNU
+ * convention.
+ * @see Parser#MAX_LINE_LENGTH
+ */
+ protected static void formatText(PrintStream out, String text, int leftMargin)
+ {
+ formatText(out, text, leftMargin, Locale.getDefault());
+ }
+
+ /**
+ * Similar to the method with the same name and three arguments, except that
+ * the caller MUST specify a non-null {@link Locale} instance.
+ * <p>
+ * Print a designated text to a {@link PrintStream}, eventually wrapping the
+ * lines of text so as to ensure that the width of each line does not overflow
+ * {@link Parser#MAX_LINE_LENGTH} columns. The line-wrapping is done with a
+ * {@link BreakIterator} using the designated {@link Locale}.
+ * <p>
+ * The text to print may contain <code>\n</code> characters. This method will
+ * force a line-break for each such character.
+ *
+ * @param out the {@link PrintStream} destination of the formatted text.
+ * @param text the text to print.
+ * @param leftMargin a positive value indicating the column position of the
+ * start of the first line. Continuation lines, if they exist, are
+ * printed starting at <code>leftMargin + 2</code> as per GNU
+ * convention.
+ * @param aLocale the {@link Locale} instance to use when constructing the
+ * {@link BreakIterator}.
+ * @see Parser#MAX_LINE_LENGTH
+ */
+ protected static void formatText(PrintStream out, String text, int leftMargin,
+ Locale aLocale)
+ {
+ BreakIterator bit = BreakIterator.getLineInstance(aLocale);
+ String[] lines = text.split("\n");
+ int length = leftMargin;
+ String leftPadding = FILLER.substring(0, leftMargin + 2);
+ for (int i = 0; i < lines.length; i++)
+ {
+ text = lines[i];
+ bit.setText(text);
+ int start = bit.first();
+ int finish;
+ while ((finish = bit.next()) != BreakIterator.DONE)
+ {
+ String word = text.substring(start, finish);
+ length += word.length();
+ if (length >= Parser.MAX_LINE_LENGTH)
+ {
+ out.println();
+ out.print(leftPadding);
+ length = word.length() + leftMargin + 2;
+ }
+ out.print(word);
+ start = finish;
+ }
+ out.println();
+ if (i != lines.length - 1)
+ {
+ length = leftMargin + 2;
+ out.print(leftPadding);
+ }
+ }
+ }
+
+ /**
* Add an option to this option group.
*
* @param opt the option to add
@@ -84,12 +168,26 @@ public class OptionGroup
*
* @param out the stream to which to print
*/
- public void printHelp(PrintStream out)
+ public void printHelp(PrintStream out, boolean longOnly)
{
// Compute maximum lengths.
int maxArgLen = 0;
- int maxShortLen = 0;
- Iterator it = options.iterator();
+ boolean shortOptionSeen = false;
+ Iterator it;
+
+ // The first pass only looks to see if we have a short option.
+ it = options.iterator();
+ while (it.hasNext())
+ {
+ Option option = (Option) it.next();
+ if (option.getShortName() != '\0')
+ {
+ shortOptionSeen = true;
+ break;
+ }
+ }
+
+ it = options.iterator();
while (it.hasNext())
{
Option option = (Option) it.next();
@@ -100,21 +198,16 @@ public class OptionGroup
// a short option if there is also a long name for
// the option.
int thisArgLen = 2;
- if (option.getShortName() != '\0')
- {
- // The name of the option plus some padding.
- thisArgLen += 4;
- }
- maxShortLen = Math.max(thisArgLen, maxShortLen);
+ if (shortOptionSeen)
+ thisArgLen += 4;
if (option.getLongName() != null)
{
- // FIXME: different if parsing in 'long option only'
- // mode.
- thisArgLen += 2 + option.getLongName().length();
+ // Handle either '-' or '--'.
+ thisArgLen += 1 + option.getLongName().length();
+ if (! longOnly)
+ ++thisArgLen;
}
- // We only need to add the argument name in once,
- // and we don't let it contribute to the width of
- // the short name.
+ // Add in the width of the argument name.
if (argName != null)
thisArgLen += 1 + argName.length();
maxArgLen = Math.max(maxArgLen, thisArgLen);
@@ -138,9 +231,16 @@ public class OptionGroup
{
if (argName != null)
{
- out.print(' ');
+ // This is a silly hack just for '-J'. We don't
+ // support joined options in general, but this option
+ // is filtered out before argument processing can see it.
+ if (option.getShortName() != 'J')
+ {
+ out.print(' ');
+ ++column;
+ }
out.print(argName);
- column += 1 + argName.length();
+ column += argName.length();
}
out.print(" ");
}
@@ -148,24 +248,24 @@ public class OptionGroup
out.print(", ");
column += 2;
}
- for (; column < maxShortLen; ++column)
+ // Indent the long option past the short options, if one
+ // was seen.
+ for (; column < (shortOptionSeen ? 6 : 2); ++column)
out.print(' ');
if (option.getLongName() != null)
{
- out.print("--");
+ out.print(longOnly ? "-" : "--");
out.print(option.getLongName());
- column += 2 + option.getLongName().length();
+ column += (longOnly ? 1 : 2) + option.getLongName().length();
if (argName != null)
{
- out.print("=" + argName);
+ out.print(" " + argName);
column += 1 + argName.length();
}
}
- for (; column < maxArgLen; ++column)
- out.print(' ');
// FIXME: should have a better heuristic for padding.
- out.print(" ");
- out.println(option.getDescription());
+ out.print(FILLER.substring(0, maxArgLen + 4 - column));
+ formatText(out, option.getDescription(), maxArgLen + 4);
}
}
}
diff --git a/tools/gnu/classpath/tools/getopt/Parser.java b/tools/gnu/classpath/tools/getopt/Parser.java
index 8d70c01d0..082cf8945 100644
--- a/tools/gnu/classpath/tools/getopt/Parser.java
+++ b/tools/gnu/classpath/tools/getopt/Parser.java
@@ -39,8 +39,11 @@
package gnu.classpath.tools.getopt;
import java.io.PrintStream;
+import java.text.BreakIterator;
+import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Iterator;
+import java.util.Locale;
/**
* An instance of this class is used to parse command-line options. It does "GNU
@@ -52,6 +55,9 @@ import java.util.Iterator;
*/
public class Parser
{
+ /** The maximum right column position. */
+ public static final int MAX_LINE_LENGTH = 80;
+
private String programName;
private String headerText;
@@ -84,6 +90,69 @@ public class Parser
}
/**
+ * Print a designated text to a {@link PrintStream}, eventually wrapping the
+ * lines of text so as to ensure that the width of each line does not overflow
+ * {@link #MAX_LINE_LENGTH} columns. The line-wrapping is done with a
+ * {@link BreakIterator} using the default {@link Locale}.
+ * <p>
+ * The text to print may contain <code>\n</code> characters. This method will
+ * force a line-break for each such character.
+ *
+ * @param out the {@link PrintStream} destination of the formatted text.
+ * @param text the text to print.
+ * @see Parser#MAX_LINE_LENGTH
+ */
+ protected static void formatText(PrintStream out, String text)
+ {
+ formatText(out, text, Locale.getDefault());
+ }
+
+ /**
+ * Similar to the method with the same name and two arguments, except that the
+ * caller MUST specify a non-null {@link Locale} instance.
+ * <p>
+ * Print a designated text to a {@link PrintStream}, eventually wrapping the
+ * lines of text so as to ensure that the width of each line does not overflow
+ * {@link #MAX_LINE_LENGTH} columns. The line-wrapping is done with a
+ * {@link BreakIterator} using the designated {@link Locale}.
+ * <p>
+ * The text to print may contain <code>\n</code> characters. This method will
+ * force a line-break for each such character.
+ *
+ * @param out the {@link PrintStream} destination of the formatted text.
+ * @param text the text to print.
+ * @param aLocale the {@link Locale} instance to use when constructing the
+ * {@link BreakIterator}.
+ * @see Parser#MAX_LINE_LENGTH
+ */
+ protected static void formatText(PrintStream out, String text, Locale aLocale)
+ {
+ BreakIterator bit = BreakIterator.getLineInstance(aLocale);
+ String[] lines = text.split("\n"); //$NON-NLS-1$
+ for (int i = 0; i < lines.length; i++)
+ {
+ text = lines[i];
+ bit.setText(text);
+ int length = 0;
+ int finish;
+ int start = bit.first();
+ while ((finish = bit.next()) != BreakIterator.DONE)
+ {
+ String word = text.substring(start, finish);
+ length += word.length();
+ if (length >= MAX_LINE_LENGTH)
+ {
+ out.println();
+ length = word.length();
+ }
+ out.print(word);
+ start = finish;
+ }
+ out.println();
+ }
+ }
+
+ /**
* Create a new parser. The program name is used when printing error messages.
* The version string is printed verbatim in response to "--version".
*
@@ -95,7 +164,10 @@ public class Parser
{
this.programName = programName;
this.longOnly = longOnly;
- defaultGroup.add(new Option("help", "print this help, then exit")
+
+ // Put standard options in their own section near the end.
+ OptionGroup finalGroup = new OptionGroup(Messages.getString("Parser.StdOptions")); //$NON-NLS-1$
+ finalGroup.add(new Option("help", Messages.getString("Parser.PrintHelp")) //$NON-NLS-1$ //$NON-NLS-2$
{
public void parsed(String argument) throws OptionException
{
@@ -103,7 +175,7 @@ public class Parser
System.exit(0);
}
});
- defaultGroup.add(new Option("version", "print version number, then exit")
+ finalGroup.add(new Option("version", Messages.getString("Parser.PrintVersion")) //$NON-NLS-1$ //$NON-NLS-2$
{
public void parsed(String argument) throws OptionException
{
@@ -111,6 +183,17 @@ public class Parser
System.exit(0);
}
});
+ finalGroup.add(new Option('J', Messages.getString("Parser.JArgument"), Messages.getString("Parser.JName")) //$NON-NLS-1$ //$NON-NLS-2$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ // -J should be handled by the appletviewer wrapper binary.
+ // We add it here so that it shows up in the --help output.
+ // Note that there is a special case for this in OptionGroup.
+ }
+ });
+ add(finalGroup);
+
add(defaultGroup);
}
@@ -155,14 +238,24 @@ public class Parser
public synchronized void add(OptionGroup group)
{
options.addAll(group.options);
- optionGroups.add(group);
+ // This ensures that the final group always appears at the end
+ // of the options.
+ if (optionGroups.isEmpty())
+ optionGroups.add(group);
+ else
+ optionGroups.add(optionGroups.size() - 1, group);
+ }
+
+ public void printHelp()
+ {
+ this.printHelp(System.out);
}
void printHelp(PrintStream out)
{
if (headerText != null)
{
- out.println(headerText);
+ formatText(out, headerText);
out.println();
}
@@ -170,19 +263,49 @@ public class Parser
while (it.hasNext())
{
OptionGroup group = (OptionGroup) it.next();
- group.printHelp(out);
- out.println();
+ // An option group might be empty, in which case we don't
+ // want to print it..
+ if (! group.options.isEmpty())
+ {
+ group.printHelp(out, longOnly);
+ out.println();
+ }
}
if (footerText != null)
- out.println(footerText);
+ formatText(out, footerText);
+ }
+
+ /**
+ * This method can be overridden by subclassses to provide some option
+ * validation. It is called by the parser after all options have been
+ * parsed. If an option validation problem is encountered, this should
+ * throw an {@link OptionException} whose message should be shown to
+ * the user.
+ * <p>
+ * It is better to do validation here than after {@link #parse(String[])}
+ * returns, because the parser will print a message referring the
+ * user to the <code>--help</code> option.
+ * <p>
+ * The base implementation does nothing.
+ *
+ * @throws OptionException the error encountered
+ */
+ protected void validate() throws OptionException
+ {
+ // Base implementation does nothing.
}
private String getArgument(String request) throws OptionException
{
++currentIndex;
if (currentIndex >= args.length)
- throw new OptionException("option '" + request + "' requires an argument");
+ {
+ String message
+ = MessageFormat.format(Messages.getString("Parser.ArgReqd"), //$NON-NLS-1$
+ new Object[] { request });
+ throw new OptionException(request);
+ }
return args[currentIndex];
}
@@ -204,7 +327,11 @@ public class Parser
}
}
if (found == null)
- throw new OptionException("unrecognized option '" + real + "'");
+ {
+ String msg = MessageFormat.format(Messages.getString("Parser.Unrecognized"), //$NON-NLS-1$
+ new Object[] { real });
+ throw new OptionException(msg);
+ }
String argument = null;
if (found.getTakesArgument())
{
@@ -215,8 +342,10 @@ public class Parser
}
else if (eq != - 1)
{
- throw new OptionException("option '" + real.substring(0, eq + index)
- + "' doesn't allow an argument");
+ String msg
+ = MessageFormat.format(Messages.getString("Parser.NoArg"), //$NON-NLS-1$
+ new Object[] { real.substring(0, eq + index) });
+ throw new OptionException(msg);
}
found.parsed(argument);
}
@@ -234,10 +363,14 @@ public class Parser
}
}
if (found == null)
- throw new OptionException("unrecognized option '-" + option + "'");
+ {
+ String msg = MessageFormat.format(Messages.getString("Parser.UnrecDash"), //$NON-NLS-1$
+ new Object[] { "" + option }); //$NON-NLS-1$
+ throw new OptionException(msg);
+ }
String argument = null;
if (found.getTakesArgument())
- argument = getArgument("-" + option);
+ argument = getArgument("-" + option); //$NON-NLS-1$
found.parsed(argument);
}
@@ -266,12 +399,12 @@ public class Parser
{
if (args[currentIndex].length() == 0
|| args[currentIndex].charAt(0) != '-'
- || "-".equals(args[currentIndex]))
+ || "-".equals(args[currentIndex])) //$NON-NLS-1$
{
files.notifyFile(args[currentIndex]);
continue;
}
- if ("--".equals(args[currentIndex]))
+ if ("--".equals(args[currentIndex])) //$NON-NLS-1$
break;
if (args[currentIndex].charAt(1) == '-')
handleLongOption(args[currentIndex], 2);
@@ -283,12 +416,19 @@ public class Parser
// Add remaining arguments to leftovers.
for (++currentIndex; currentIndex < args.length; ++currentIndex)
files.notifyFile(args[currentIndex]);
+ // See if something went wrong.
+ validate();
}
catch (OptionException err)
{
- System.err.println(programName + ": " + err.getMessage());
- System.err.println(programName + ": Try '" + programName
- + " --help' for more information.");
+ System.err.println(programName + ": " + err.getMessage()); //$NON-NLS-1$
+ String fmt;
+ if (longOnly)
+ fmt = Messages.getString("Parser.TryHelpShort"); //$NON-NLS-1$
+ else
+ fmt = Messages.getString("Parser.TryHelpLong"); //$NON-NLS-1$
+ String msg = MessageFormat.format(fmt, new Object[] { programName });
+ System.err.println(programName + ": " + msg); //$NON-NLS-1$
System.exit(1);
}
}
diff --git a/tools/gnu/classpath/tools/giop/GRMIC.java b/tools/gnu/classpath/tools/giop/GRMIC.java
index a372cfd66..c910d7083 100644
--- a/tools/gnu/classpath/tools/giop/GRMIC.java
+++ b/tools/gnu/classpath/tools/giop/GRMIC.java
@@ -104,6 +104,17 @@ public class GRMIC
else
HelpPrinter.printHelpAndExit(HelpPath);
}
+ else if (c.equals("-classpath"))
+ {
+ int f = i + 1;
+ if (f < args.length)
+ {
+ compiler.setClassPath(args[f]);
+ i++;
+ }
+ else
+ HelpPrinter.printHelpAndExit(HelpPath);
+ }
else if (c.charAt(0) != '-')
// No more options - start of class list.
{
@@ -124,17 +135,7 @@ public class GRMIC
if (args[i].charAt(0) != '-')
{
compiler.reset();
- Class c = null;
- try
- {
- c = Thread.currentThread().getContextClassLoader().loadClass(
- args[i]);
- }
- catch (ClassNotFoundException e)
- {
- System.err.println(args[i] + " class not found.");
- System.exit(1);
- }
+ Class c = compiler.loadClass(args[i]);
compiler.compile(c);
String packag = compiler.getPackageName().replace('.', '/');
diff --git a/tools/gnu/classpath/tools/giop/GRMIC.txt b/tools/gnu/classpath/tools/giop/GRMIC.txt
index 08aaf148f..875bcdbcf 100644
--- a/tools/gnu/classpath/tools/giop/GRMIC.txt
+++ b/tools/gnu/classpath/tools/giop/GRMIC.txt
@@ -9,18 +9,20 @@ Please report bugs at http://www.gnu.org/software/classpath/bugs.html
Usage: grmic <options> <class names>
where <options> includes:
- -poa Generate the Servant based ties (default)
- -impl Generate the obsoleted ObjectImpl based ties
- (for backward compatibility)
- -nowarn Show no warnings
- -nowrite Do not write any files (check for errors only)
- -d <folder> Place generated files into the given folder
+ -poa Generate the Servant based ties (default)
+ -impl Generate the obsoleted ObjectImpl based ties
+ (for backward compatibility)
+ -nowarn Show no warnings
+ -nowrite Do not write any files (check for errors only)
+ -d <folder> Place generated files into the given folder
+ -classpath <path> Specifies the path, where to find the classes being
+ compiled
- -help Print this help text
- -v Print version
- -verbose Verbose output
- -force Try to generate code even if the input classes seem not
- consistent with RMI specification.
+ -help Print this help text
+ -v Print version
+ -verbose Verbose output
+ -force Try to generate code even if the input classes seem not
+ consistent with RMI specification.
and <class names> can include one or more non abstract classes that implement
diff --git a/tools/gnu/classpath/tools/giop/grmic/GiopRmicCompiler.java b/tools/gnu/classpath/tools/giop/grmic/GiopRmicCompiler.java
index 4beba1c9f..6d895a14c 100644
--- a/tools/gnu/classpath/tools/giop/grmic/GiopRmicCompiler.java
+++ b/tools/gnu/classpath/tools/giop/grmic/GiopRmicCompiler.java
@@ -23,7 +23,11 @@ package gnu.classpath.tools.giop.grmic;
import gnu.classpath.tools.AbstractMethodGenerator;
+import java.io.File;
import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.ArrayList;
@@ -33,6 +37,7 @@ import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Properties;
+import java.util.StringTokenizer;
import java.util.TreeSet;
/**
@@ -104,6 +109,11 @@ public class GiopRmicCompiler
* Force mode - do not check the exceptions
*/
protected boolean force = false;
+
+ /**
+ * The class loader to load the class being compiled.
+ */
+ ClassLoader classLoader;
/**
* Clear data, preparing for the next compilation.
@@ -116,6 +126,78 @@ public class GiopRmicCompiler
methods.clear();
vars.clear();
}
+
+ /**
+ * Set the class path (handle the -classpath key)
+ *
+ * @param classPath the class path to set.
+ */
+ public void setClassPath(String classPath)
+ {
+ classLoader = Thread.currentThread().getContextClassLoader();
+ StringTokenizer tok = new StringTokenizer(classPath, File.pathSeparator,
+ true);
+ ArrayList urls = new ArrayList(tok.countTokens());
+ String s = null;
+ try
+ {
+ while (tok.hasMoreTokens())
+ {
+ s = tok.nextToken();
+ if (s.equals(File.pathSeparator))
+ urls.add(new File(".").toURL());
+ else
+ {
+ urls.add(new File(s).toURL());
+ if (tok.hasMoreTokens())
+ {
+ // Skip the separator.
+ tok.nextToken();
+ // If the classpath ended with a separator,
+ // append the current directory.
+ if (! tok.hasMoreTokens())
+ urls.add(new File(".").toURL());
+ }
+ }
+ }
+ }
+ catch (MalformedURLException ex)
+ {
+ System.err.println("Malformed path '" + s + "' in classpath '"
+ + classPath + "'");
+ System.exit(1);
+ }
+ URL[] u = new URL[urls.size()];
+ for (int i = 0; i < u.length; i++)
+ {
+ u[i] = (URL) urls.get(i);
+ }
+
+ classLoader = new URLClassLoader(u, classLoader);
+ }
+
+ /**
+ * Loads the class with the given name (uses class path, if applicable)
+ *
+ * @param name the name of the class.
+ */
+ public Class loadClass(String name)
+ {
+ ClassLoader loader = classLoader;
+ if (loader == null)
+ loader = Thread.currentThread().getContextClassLoader();
+ try
+ {
+ return loader.loadClass(name);
+ }
+ catch (ClassNotFoundException e)
+ {
+ System.err.println(name+" not found on "+loader);
+ System.exit(1);
+ // Unreacheable code.
+ return null;
+ }
+ }
/**
* Compile the given class (the instance of Remote), generating the stub and
@@ -193,12 +275,12 @@ public class GiopRmicCompiler
remEx = true;
break;
}
- if (! remEx && !force)
- throw new CompilationError(m[i].getName() + ", defined in "
- + c.getName()
- + ", does not throw "
- + RemoteException.class.getName());
- }
+ }
+ if (! remEx && !force)
+ throw new CompilationError(m[i].getName() + ", defined in "
+ + c.getName()
+ + ", does not throw "
+ + RemoteException.class.getName());
AbstractMethodGenerator mm = createMethodGenerator(m[i]);
methods.add(mm);
}
diff --git a/tools/gnu/classpath/tools/jar/Action.java b/tools/gnu/classpath/tools/jar/Action.java
index fea60f797..6363157ae 100644
--- a/tools/gnu/classpath/tools/jar/Action.java
+++ b/tools/gnu/classpath/tools/jar/Action.java
@@ -46,5 +46,6 @@ public abstract class Action
{
}
- public abstract void run(Main parameters) throws IOException;
+ public abstract void run(Main parameters)
+ throws IOException;
}
diff --git a/tools/gnu/classpath/tools/jar/Creator.java b/tools/gnu/classpath/tools/jar/Creator.java
index a636fca6b..55159660d 100644
--- a/tools/gnu/classpath/tools/jar/Creator.java
+++ b/tools/gnu/classpath/tools/jar/Creator.java
@@ -46,16 +46,23 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.text.MessageFormat;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.Iterator;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
public class Creator
extends Action
{
- ZipOutputStream outputStream;
+ JarOutputStream outputStream;
+ HashSet writtenItems = new HashSet();
+ // The manifest to use, or null if we don't want a manifest.
+ Manifest manifest;
private long copyFile(CRC32 crc, InputStream is, OutputStream output)
throws IOException
@@ -76,8 +83,20 @@ public class Creator
}
protected void writeFile(boolean isDirectory, InputStream inputFile,
- String filename, boolean verbose) throws IOException
+ String filename, boolean verbose)
+ throws IOException
{
+ if (writtenItems.contains(filename))
+ {
+ if (verbose)
+ {
+ String msg = MessageFormat.format(Messages.getString("Creator.Ignoring"), //$NON-NLS-1$
+ new Object[] { filename });
+ System.err.println(msg);
+ }
+ return;
+ }
+
ByteArrayOutputStream out = new ByteArrayOutputStream();
CRC32 crc = new CRC32();
long size;
@@ -97,6 +116,7 @@ public class Creator
outputStream.putNextEntry(entry);
out.writeTo(outputStream);
outputStream.closeEntry();
+ writtenItems.add(filename);
if (verbose)
{
@@ -106,8 +126,15 @@ public class Creator
perc = 0;
else
perc = 100 - (100 * csize) / size;
- System.out.println("adding: " + filename + " (in=" + size + ") (out="
- + entry.getSize() + ") (stored " + perc + "%)");
+ String msg = MessageFormat.format(Messages.getString("Creator.Adding"), //$NON-NLS-1$
+ new Object[]
+ {
+ filename,
+ Long.valueOf(size),
+ Long.valueOf(entry.getSize()),
+ Long.valueOf(perc)
+ });
+ System.err.println(msg);
}
}
@@ -140,7 +167,7 @@ public class Creator
String[] files = entry.file.list();
for (int i = 0; i < files.length; ++i)
addEntries(result, new Entry(new File(entry.file, files[i]),
- entry.name + '/' + files[i]));
+ entry.name + files[i]));
}
else
result.add(entry);
@@ -158,35 +185,63 @@ public class Creator
return allEntries;
}
- protected ArrayList writeCommandLineEntries(Main parameters, File zipFile)
+ private void writeCommandLineEntries(Main parameters)
throws IOException
{
- outputStream = new ZipOutputStream(
- new BufferedOutputStream(
- new FileOutputStream(
- zipFile)));
- outputStream.setMethod(parameters.storageMode);
+ // We've already written the manifest, make sure to mark it.
+ writtenItems.add("META-INF/"); //$NON-NLS-1$
+ writtenItems.add(JarFile.MANIFEST_NAME);
+
ArrayList allEntries = getAllEntries(parameters);
- Iterator it = parameters.entries.iterator();
+ Iterator it = allEntries.iterator();
while (it.hasNext())
{
Entry entry = (Entry) it.next();
writeFile(entry.file, entry.name, parameters.verbose);
}
- return allEntries;
+ }
+
+ protected Manifest createManifest(Main parameters)
+ throws IOException
+ {
+ if (! parameters.wantManifest)
+ return null;
+ if (parameters.manifestFile != null)
+ {
+ // User specified a manifest file.
+ InputStream contents = new FileInputStream(parameters.manifestFile);
+ return new Manifest(contents);
+ }
+ return new Manifest();
+ }
+
+ protected void writeCommandLineEntries(Main parameters, OutputStream os)
+ throws IOException
+ {
+ manifest = createManifest(parameters);
+ outputStream = new JarOutputStream(os, manifest);
+ // FIXME: in Classpath this sets the method too late for the
+ // manifest file.
+ outputStream.setMethod(parameters.storageMode);
+ writeCommandLineEntries(parameters);
}
protected void close() throws IOException
{
- // FIXME: handle manifest options here.
- // FIXME: handle index file here ...?
outputStream.finish();
outputStream.close();
}
public void run(Main parameters) throws IOException
{
- writeCommandLineEntries(parameters, parameters.archiveFile);
+ if (parameters.archiveFile == null || parameters.archiveFile.equals("-")) //$NON-NLS-1$
+ writeCommandLineEntries(parameters, System.out);
+ else
+ {
+ OutputStream os
+ = new BufferedOutputStream(new FileOutputStream(parameters.archiveFile));
+ writeCommandLineEntries(parameters, os);
+ }
close();
}
}
diff --git a/tools/gnu/classpath/tools/jar/Extractor.java b/tools/gnu/classpath/tools/jar/Extractor.java
index 245f5e36c..203ff0566 100644
--- a/tools/gnu/classpath/tools/jar/Extractor.java
+++ b/tools/gnu/classpath/tools/jar/Extractor.java
@@ -38,17 +38,22 @@
package gnu.classpath.tools.jar;
+import java.io.BufferedInputStream;
import java.io.File;
+import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.util.Enumeration;
+import java.text.MessageFormat;
import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
+import java.util.zip.ZipInputStream;
public class Extractor
extends Action
{
+ // This is a set of all the items specified on the command line.
+ private WorkSet allItems;
+
private void copyFile(InputStream input, File output) throws IOException
{
FileOutputStream os = new FileOutputStream(output);
@@ -65,18 +70,38 @@ public class Extractor
public void run(Main parameters) throws IOException
{
- ZipFile zip = new ZipFile(parameters.archiveFile);
- Enumeration e = zip.entries();
- while (e.hasMoreElements())
+ // Figure out what we want to extract.
+ allItems = new WorkSet(parameters.entries);
+ // Open the input file.
+ ZipInputStream zis;
+ File zfile = parameters.archiveFile;
+ if (zfile == null || "-".equals(zfile.getName())) //$NON-NLS-1$
+ zis = new ZipInputStream(System.in);
+ else
{
- ZipEntry entry = (ZipEntry) e.nextElement();
+ InputStream ins = new BufferedInputStream(new FileInputStream(zfile));
+ zis = new ZipInputStream(ins);
+ }
+ // Extract stuff.
+ while (true)
+ {
+ ZipEntry entry = zis.getNextEntry();
+ if (entry == null)
+ break;
+ if (! allItems.contains(entry.getName()))
+ continue;
File file = new File(entry.getName());
if (entry.isDirectory())
{
if (file.mkdirs())
{
if (parameters.verbose)
- System.out.println(" created: " + file);
+ {
+ String msg
+ = MessageFormat.format(Messages.getString("Extractor.Created"), //$NON-NLS-1$
+ new Object[] { file });
+ System.err.println(msg);
+ }
}
continue;
}
@@ -85,15 +110,17 @@ public class Extractor
if (parent != null)
parent.mkdirs();
- InputStream input = zip.getInputStream(entry);
- copyFile(input, file);
- input.close();
+ copyFile(zis, file);
if (parameters.verbose)
{
- String leader = (entry.getMethod() == ZipEntry.STORED ? " extracted"
- : " inflated");
- System.out.println(leader + ": " + file);
+ String fmt;
+ if (entry.getMethod() == ZipEntry.STORED)
+ fmt = Messages.getString("Extractor.Extracted"); //$NON-NLS-1$
+ else
+ fmt = Messages.getString("Extractor.Inflated"); //$NON-NLS-1$
+ String msg = MessageFormat.format(fmt, new Object[] { file });
+ System.err.println(msg);
}
}
}
diff --git a/tools/gnu/classpath/tools/jar/Indexer.java b/tools/gnu/classpath/tools/jar/Indexer.java
new file mode 100644
index 000000000..aae25f821
--- /dev/null
+++ b/tools/gnu/classpath/tools/jar/Indexer.java
@@ -0,0 +1,144 @@
+/* Indexer.java -- add index.list file to jar
+ 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.jar;
+
+import gnu.java.net.IndexListParser;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.text.MessageFormat;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.StringTokenizer;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+public class Indexer
+ extends Updater
+{
+ private void indexJarFile(StringBuffer result, File fileName,
+ boolean verbose)
+ throws IOException
+ {
+ if (verbose)
+ {
+ String msg = MessageFormat.format(Messages.getString("Indexer.Indexing"), //$NON-NLS-1$
+ new Object[] { fileName });
+ System.err.println(msg);
+ }
+ JarFile jf = new JarFile(fileName);
+
+ // Index the files in this jar.
+ // The results look a little better if we keep them
+ // in insertion order.
+ LinkedHashSet entries = new LinkedHashSet();
+ Enumeration e = jf.entries();
+ while (e.hasMoreElements())
+ {
+ JarEntry entry = (JarEntry) e.nextElement();
+ String name = entry.getName();
+ if (name.startsWith("META-INF/")) //$NON-NLS-1$
+ continue;
+ int index = name.lastIndexOf('/');
+ if (index != -1)
+ name = name.substring(0, index);
+ entries.add(name);
+ }
+ if (! entries.isEmpty())
+ {
+ result.append(fileName);
+ // Any line ending will do.
+ result.append('\n');
+ Iterator i = entries.iterator();
+ while (i.hasNext())
+ {
+ result.append(i.next());
+ result.append('\n');
+ }
+ // Paragraph break.
+ result.append('\n');
+ }
+
+ // Now read pointed-to jars.
+ Manifest m = jf.getManifest();
+ if (m != null)
+ {
+ File parent = fileName.getParentFile();
+ Attributes attrs = m.getMainAttributes();
+ String jars = attrs.getValue(Attributes.Name.CLASS_PATH);
+ if (jars != null)
+ {
+ StringTokenizer st = new StringTokenizer(jars, " "); //$NON-NLS-1$
+ while (st.hasMoreTokens())
+ {
+ String name = st.nextToken();
+ indexJarFile(result, new File(parent, name), verbose);
+ }
+ }
+ }
+
+ jf.close();
+ }
+
+ protected void writeCommandLineEntries(Main parameters, OutputStream os)
+ throws IOException
+ {
+ // This is a pretty lame design. We know the super call will
+ // only have side effects and won't actually write anything important.
+ super.writeCommandLineEntries(parameters, os);
+
+ // Now compute our index file and write it.
+ StringBuffer contents = new StringBuffer();
+ indexJarFile(contents, parameters.archiveFile, parameters.verbose);
+ if (contents.length() != 0)
+ {
+ // Insert in reverse order to avoid computing anything.
+ contents.insert(0, "1.0\n\n"); //$NON-NLS-1$
+ contents.insert(0, IndexListParser.JAR_INDEX_VERSION_KEY);
+ ByteArrayInputStream in
+ = new ByteArrayInputStream(contents.toString().getBytes());
+ writeFile(false, in, IndexListParser.JAR_INDEX_FILE, parameters.verbose);
+ }
+ }
+}
diff --git a/tools/gnu/classpath/tools/jar/Lister.java b/tools/gnu/classpath/tools/jar/Lister.java
index fe5792e76..98275f789 100644
--- a/tools/gnu/classpath/tools/jar/Lister.java
+++ b/tools/gnu/classpath/tools/jar/Lister.java
@@ -38,32 +38,54 @@
package gnu.classpath.tools.jar;
+import java.io.BufferedInputStream;
import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.text.MessageFormat;
import java.util.Date;
-import java.util.Enumeration;
import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
+import java.util.zip.ZipInputStream;
public class Lister
extends Action
{
- private void listJar(File jarFile, boolean verbose) throws IOException
+ private WorkSet allItems;
+
+ private long readUntilEnd(InputStream is) throws IOException
+ {
+ byte[] buffer = new byte[5 * 1024];
+ long result = 0;
+ while (true)
+ {
+ int r = is.read(buffer);
+ if (r == -1)
+ break;
+ result += r;
+ }
+ return result;
+ }
+
+ private void listJar(ZipInputStream zis, boolean verbose) throws IOException
{
- ZipFile zipFile = new ZipFile(jarFile);
- Enumeration i = zipFile.entries();
MessageFormat format = null;
if (verbose)
format = new MessageFormat(" {0,date,E M dd HH:mm:ss z yyyy} {1}");
- while (i.hasMoreElements())
+ while (true)
{
- ZipEntry entry = (ZipEntry) i.nextElement();
+ ZipEntry entry = zis.getNextEntry();
+ if (entry == null)
+ break;
+ if (! allItems.contains(entry.getName()))
+ continue;
if (verbose)
{
+ // Read the stream; entry.getSize() is unreliable.
+ // (Also, we're just going to read it anyway.)
+ long size = readUntilEnd(zis);
// No easy way to right-justify the size using
// MessageFormat -- how odd.
- long size = entry.getSize();
String s = " " + size;
int index = Math.min(s.length() - 5, 5);
System.out.print(s.substring(index));
@@ -74,11 +96,17 @@ public class Lister
else
System.out.println(entry.getName());
}
- zipFile.close();
}
public void run(Main parameters) throws IOException
{
- listJar(parameters.archiveFile, parameters.verbose);
+ allItems = new WorkSet(parameters.entries);
+ File file = parameters.archiveFile;
+ ZipInputStream zis;
+ if (file == null || "-".equals(file.getName()))
+ zis = new ZipInputStream(System.in);
+ else
+ zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(file)));
+ listJar(zis, parameters.verbose);
}
}
diff --git a/tools/gnu/classpath/tools/jar/Main.java b/tools/gnu/classpath/tools/jar/Main.java
index ee4da3c27..8ea770bb6 100644
--- a/tools/gnu/classpath/tools/jar/Main.java
+++ b/tools/gnu/classpath/tools/jar/Main.java
@@ -47,41 +47,53 @@ import gnu.classpath.tools.getopt.Parser;
import java.io.File;
import java.io.IOException;
+import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.zip.ZipOutputStream;
public class Main
{
- // The mode of operation. This is the class representing
- // the action; we make a new instance before using it. It
- // must be a subclass of Action. 'null' means the mode
- // has not yet been set.
+ /** The mode of operation. This is the class representing
+ * the action; we make a new instance before using it. It
+ * must be a subclass of Action. 'null' means the mode
+ * has not yet been set. */
Class operationMode;
- // The archive file name.
+ /** The archive file name. */
File archiveFile;
- // The zip storage mode.
+ /** The zip storage mode. */
int storageMode = ZipOutputStream.DEFLATED;
- // True if we should read file names from stdin.
+ /** True if we should read file names from stdin. */
boolean readNamesFromStdin = false;
- // True for verbose mode.
+ /** True for verbose mode. */
boolean verbose = false;
- // True if we want a manifest file.
+ /** True if we want a manifest file. */
boolean wantManifest = true;
- // Name of manifest file to use.
+ /** Name of manifest file to use. */
File manifestFile;
- // A list of Entry objects, each describing a file to write.
+ /** A list of Entry objects, each describing a file to write. */
ArrayList entries = new ArrayList();
- // Used only while parsing.
+ /** Used only while parsing, holds the first argument for -C. */
String changedDirectory;
+ void setArchiveFile(String filename) throws OptionException
+ {
+ if (archiveFile != null)
+ {
+ String fmt = MessageFormat.format(Messages.getString("Main.ArchiveAlreadySet"), //$NON-NLS-1$
+ new Object[] { archiveFile });
+ throw new OptionException(fmt);
+ }
+ archiveFile = new File(filename);
+ }
+
class HandleFile
extends FileArgumentCallback
{
@@ -112,57 +124,96 @@ public class Main
this.mode = mode;
}
+ public ModeOption(char shortName, String description, String argName,
+ Class mode)
+ {
+ super(shortName, description, argName);
+ this.mode = mode;
+ }
+
public void parsed(String argument) throws OptionException
{
if (operationMode != null)
- throw new OptionException("operation mode already specified");
+ throw new OptionException(Messages.getString("Main.ModeAlreaySet")); //$NON-NLS-1$
operationMode = mode;
+ // We know this is only the case for -i.
+ if (argument != null)
+ setArchiveFile(argument);
+ }
+ }
+
+ private class JarParser extends ClasspathToolParser
+ {
+ public JarParser(String name)
+ {
+ super(name);
+ }
+
+ protected void validate() throws OptionException
+ {
+ if (operationMode == null)
+ throw new OptionException(Messages.getString("Main.MustSpecify")); //$NON-NLS-1$
+ if (changedDirectory != null)
+ throw new OptionException(Messages.getString("Main.TwoArgsReqd")); //$NON-NLS-1$
+ if (! wantManifest && manifestFile != null)
+ throw new OptionException(Messages.getString("Main.CantHaveBoth")); //$NON-NLS-1$
+ if (operationMode == Indexer.class)
+ {
+ // Some extra validation for -i.
+ if (! entries.isEmpty())
+ throw new OptionException(Messages.getString("Main.NoFilesWithi")); //$NON-NLS-1$
+ if (! wantManifest)
+ throw new OptionException(Messages.getString("Main.NoMAndi")); //$NON-NLS-1$
+ if (manifestFile != null)
+ throw new OptionException(Messages.getString("Main.AnotherNomAndi")); //$NON-NLS-1$
+ }
}
}
private Parser initializeParser()
{
- Parser p = new ClasspathToolParser("jar");
- p.setHeader("Usage: jar -ctxu [OPTIONS] jar-file [-C DIR FILE] FILE...");
-
- OptionGroup grp = new OptionGroup("Operation mode");
- grp.add(new ModeOption('c', "create a new archive", Creator.class));
- grp.add(new ModeOption('x', "extract from archive", Extractor.class));
- grp.add(new ModeOption('t', "list archive contents", Lister.class));
- grp.add(new ModeOption('u', "update archive", Updater.class));
+ Parser p = new JarParser("jar"); //$NON-NLS-1$
+ p.setHeader(Messages.getString("Main.Usage")); //$NON-NLS-1$
+
+ OptionGroup grp = new OptionGroup(Messages.getString("Main.OpMode")); //$NON-NLS-1$
+ grp.add(new ModeOption('c', Messages.getString("Main.Create"), Creator.class)); //$NON-NLS-1$
+ grp.add(new ModeOption('x', Messages.getString("Main.Extract"), Extractor.class)); //$NON-NLS-1$
+ grp.add(new ModeOption('t', Messages.getString("Main.List"), Lister.class)); //$NON-NLS-1$
+ grp.add(new ModeOption('u', Messages.getString("Main.Update"), Updater.class)); //$NON-NLS-1$
+ // Note that -i works in-place and explicitly requires a file name.
+ grp.add(new ModeOption('i', Messages.getString("Main.Index"), Messages.getString("Main.FileArg"), Indexer.class)); //$NON-NLS-1$ //$NON-NLS-2$
p.add(grp);
- grp = new OptionGroup("Operation modifiers");
- grp.add(new Option('f', "specify archive file name", "FILE")
+ grp = new OptionGroup(Messages.getString("Main.OpMods")); //$NON-NLS-1$
+ grp.add(new Option('f', Messages.getString("Main.ArchiveName"), Messages.getString("Main.FileArg2")) //$NON-NLS-1$ //$NON-NLS-2$
{
public void parsed(String argument) throws OptionException
{
- // FIXME: error if already set.
- archiveFile = new File(argument);
+ setArchiveFile(argument);
}
});
- grp.add(new Option('0', "store only; no ZIP compression")
+ grp.add(new Option('0', Messages.getString("Main.NoZip")) //$NON-NLS-1$
{
public void parsed(String argument) throws OptionException
{
storageMode = ZipOutputStream.STORED;
}
});
- grp.add(new Option('v', "verbose operation")
+ grp.add(new Option('v', Messages.getString("Main.Verbose")) //$NON-NLS-1$
{
public void parsed(String argument) throws OptionException
{
verbose = true;
}
});
- grp.add(new Option('M', "do not create a manifest file")
+ grp.add(new Option('M', Messages.getString("Main.NoManifest")) //$NON-NLS-1$
{
public void parsed(String argument) throws OptionException
{
wantManifest = false;
}
});
- grp.add(new Option('m', "specify manifest file", "FILE")
+ grp.add(new Option('m', Messages.getString("Main.ManifestName"), Messages.getString("Main.ManifestArgName")) //$NON-NLS-1$ //$NON-NLS-2$
{
public void parsed(String argument) throws OptionException
{
@@ -172,9 +223,9 @@ public class Main
// -@
p.add(grp);
- grp = new OptionGroup("File name selection");
- grp.add(new Option('C', "change to directory before the next file",
- "DIR FILE")
+ grp = new OptionGroup(Messages.getString("Main.FileNameGroup")); //$NON-NLS-1$
+ grp.add(new Option('C', Messages.getString("Main.ChangeDir"), //$NON-NLS-1$
+ Messages.getString("Main.ChangeDirArg")) //$NON-NLS-1$
{
public void parsed(String argument) throws OptionException
{
@@ -182,23 +233,18 @@ public class Main
}
});
p.add(grp);
- // -i - need to parse classes
return p;
}
- private void run(String[] args) throws OptionException,
- InstantiationException, IllegalAccessException, IOException
+ private void run(String[] args)
+ throws InstantiationException, IllegalAccessException, IOException
{
Parser p = initializeParser();
// Special hack to emulate old tar-style commands.
- if (args[0].charAt(0) != '-')
+ if (args.length > 0 && args[0].charAt(0) != '-')
args[0] = '-' + args[0];
p.parse(args, new HandleFile());
- if (operationMode == null)
- throw new OptionException("must specify one of -t, -c, -u, or -x");
- if (changedDirectory != null)
- throw new OptionException("-C argument requires both directory and filename");
Action t = (Action) operationMode.newInstance();
t.run(this);
}
@@ -210,14 +256,9 @@ public class Main
{
jarprogram.run(args);
}
- catch (OptionException arg)
- {
- System.err.println("jar: " + arg.getMessage());
- System.exit(1);
- }
catch (Exception e)
{
- System.err.println("jar: internal error:");
+ System.err.println(Messages.getString("Main.InternalError")); //$NON-NLS-1$
e.printStackTrace(System.err);
System.exit(1);
}
diff --git a/tools/gnu/classpath/tools/jar/Messages.java b/tools/gnu/classpath/tools/jar/Messages.java
new file mode 100644
index 000000000..ea54bd08f
--- /dev/null
+++ b/tools/gnu/classpath/tools/jar/Messages.java
@@ -0,0 +1,67 @@
+/* Messages.java -- localization support for jar
+ 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.jar;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class Messages
+{
+ private static final String BUNDLE_NAME
+ = "gnu.classpath.tools.jar.messages"; //$NON-NLS-1$
+
+ private static final ResourceBundle RESOURCE_BUNDLE
+ = ResourceBundle.getBundle(BUNDLE_NAME);
+
+ private Messages()
+ {
+ }
+
+ public static String getString(String key)
+ {
+ try
+ {
+ return RESOURCE_BUNDLE.getString(key);
+ }
+ catch (MissingResourceException e)
+ {
+ return '!' + key + '!';
+ }
+ }
+}
diff --git a/tools/gnu/classpath/tools/jar/Updater.java b/tools/gnu/classpath/tools/jar/Updater.java
index 9046b42b0..29586befd 100644
--- a/tools/gnu/classpath/tools/jar/Updater.java
+++ b/tools/gnu/classpath/tools/jar/Updater.java
@@ -38,41 +38,51 @@
package gnu.classpath.tools.jar;
+import java.io.BufferedOutputStream;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
-import java.util.ArrayList;
+import java.io.OutputStream;
import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Iterator;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
public class Updater
extends Creator
{
+ JarFile inputJar;
+
+ protected Manifest createManifest(Main parameters) throws IOException
+ {
+ Manifest result = inputJar.getManifest();
+ if (result == null)
+ return super.createManifest(parameters);
+ if (parameters.manifestFile != null)
+ result.read(new FileInputStream(parameters.manifestFile));
+ return result;
+ }
+
public void run(Main parameters) throws IOException
{
+ // Set this early so that createManifest can use it.
+ inputJar = new JarFile(parameters.archiveFile);
+
// Write all the new entries to a temporary file.
File tmpFile = File.createTempFile("jarcopy", null);
- ArrayList newEntries = writeCommandLineEntries(parameters, tmpFile);
- HashSet set = new HashSet();
- Iterator it = newEntries.iterator();
- while (it.hasNext())
- {
- Entry entry = (Entry) it.next();
- set.add(entry.name);
- }
+ OutputStream os = new BufferedOutputStream(new FileOutputStream(tmpFile));
+ writeCommandLineEntries(parameters, os);
// Now read the old file and copy extra entries to the new file.
- ZipFile zip = new ZipFile(parameters.archiveFile);
- Enumeration e = zip.entries();
+ Enumeration e = inputJar.entries();
while (e.hasMoreElements())
{
ZipEntry entry = (ZipEntry) e.nextElement();
- if (set.contains(entry.getName()))
+ if (writtenItems.contains(entry.getName()))
continue;
- writeFile(entry.isDirectory(), zip.getInputStream(entry),
- zip.getName(), parameters.verbose);
+ writeFile(entry.isDirectory(), inputJar.getInputStream(entry),
+ entry.getName(), parameters.verbose);
}
close();
diff --git a/tools/gnu/classpath/tools/jar/WorkSet.java b/tools/gnu/classpath/tools/jar/WorkSet.java
new file mode 100644
index 000000000..ff0b48786
--- /dev/null
+++ b/tools/gnu/classpath/tools/jar/WorkSet.java
@@ -0,0 +1,86 @@
+/* WorkSet.java -- Helper to track what files to work on
+ 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.jar;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+
+public class WorkSet
+{
+ private HashSet allItems;
+
+ private void initSet(ArrayList entries)
+ {
+ if (entries == null || entries.isEmpty())
+ return;
+ allItems = new HashSet();
+ Iterator it = entries.iterator();
+ while (it.hasNext())
+ {
+ Entry entry = (Entry) it.next();
+ int len = entry.name.length();
+ while (len > 0 && entry.name.charAt(len - 1) == '/')
+ --len;
+ String name = entry.name.substring(0, len);
+ allItems.add(name);
+ }
+ }
+
+ public WorkSet(ArrayList entries)
+ {
+ initSet(entries);
+ }
+
+ public boolean contains(String filename)
+ {
+ if (allItems == null)
+ return true;
+ while (filename.length() > 0)
+ {
+ if (allItems.contains(filename))
+ return true;
+ int index = filename.lastIndexOf('/');
+ if (index == -1)
+ break;
+ filename = filename.substring(0, index);
+ }
+ return false;
+ }
+}
diff --git a/tools/gnu/classpath/tools/jarsigner/JarSigner.java b/tools/gnu/classpath/tools/jarsigner/JarSigner.java
index 40bee9fe9..8d3bc31af 100644
--- a/tools/gnu/classpath/tools/jarsigner/JarSigner.java
+++ b/tools/gnu/classpath/tools/jarsigner/JarSigner.java
@@ -141,7 +141,7 @@ public class JarSigner
main.isInternalSF());
log.finer("Created .DSA file"); //$NON-NLS-1$
if (main.isVerbose())
- System.out.println(Messages.getString("JarSigner.11") + dsaFileName); //$NON-NLS-1$
+ System.out.println(Messages.getString("JarSigner.8") + dsaFileName); //$NON-NLS-1$
// cleanup
outSignedJarFile.close();
diff --git a/tools/gnu/classpath/tools/jarsigner/Main.java b/tools/gnu/classpath/tools/jarsigner/Main.java
index f460a96cc..6928bce59 100644
--- a/tools/gnu/classpath/tools/jarsigner/Main.java
+++ b/tools/gnu/classpath/tools/jarsigner/Main.java
@@ -39,9 +39,13 @@ exception statement from your version. */
package gnu.classpath.tools.jarsigner;
import gnu.classpath.SystemProperties;
-import gnu.classpath.tools.HelpPrinter;
import gnu.classpath.tools.common.CallbackUtil;
import gnu.classpath.tools.common.ProviderUtil;
+import gnu.classpath.tools.getopt.ClasspathToolParser;
+import gnu.classpath.tools.getopt.FileArgumentCallback;
+import gnu.classpath.tools.getopt.Option;
+import gnu.classpath.tools.getopt.OptionException;
+import gnu.classpath.tools.getopt.OptionGroup;
import gnu.java.security.OID;
import gnu.java.security.Registry;
import gnu.javax.security.auth.callback.ConsoleCallbackHandler;
@@ -61,6 +65,7 @@ import java.security.Security;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
+import java.util.ArrayList;
import java.util.Locale;
import java.util.jar.Attributes.Name;
import java.util.logging.Logger;
@@ -81,8 +86,8 @@ import javax.security.auth.callback.UnsupportedCallbackException;
*/
public class Main
{
- private static final Logger log = Logger.getLogger(Main.class.getName());
- private static final String HELP_PATH = "jarsigner/jarsigner.txt"; //$NON-NLS-1$
+ protected static final Logger log = Logger.getLogger(Main.class.getName());
+ static final String KEYTOOL_TOOL = "jarsigner"; //$NON-NLS-1$
private static final Locale EN_US_LOCALE = new Locale("en", "US"); //$NON-NLS-1$ //$NON-NLS-2$
static final String DIGEST = "SHA1-Digest"; //$NON-NLS-1$
static final String DIGEST_MANIFEST = "SHA1-Digest-Manifest"; //$NON-NLS-1$
@@ -91,20 +96,20 @@ public class Main
static final OID DSA_SIGNATURE_OID = new OID(Registry.DSA_OID_STRING);
static final OID RSA_SIGNATURE_OID = new OID(Registry.RSA_OID_STRING);
- private boolean verify;
- private String ksURL;
- private String ksType;
- private String password;
- private String ksPassword;
- private String sigFileName;
- private String signedJarFileName;
- private boolean verbose;
- private boolean certs;
- private boolean internalSF;
- private boolean sectionsOnly;
- private String providerClassName;
- private String jarFileName;
- private String alias;
+ protected boolean verify;
+ protected String ksURL;
+ protected String ksType;
+ protected String password;
+ protected String ksPassword;
+ protected String sigFileName;
+ protected String signedJarFileName;
+ protected boolean verbose;
+ protected boolean certs;
+ protected boolean internalSF;
+ protected boolean sectionsOnly;
+ protected String providerClassName;
+ protected String jarFileName;
+ protected String alias;
protected Provider provider;
private boolean providerInstalled;
@@ -115,6 +120,9 @@ public class Main
private Certificate[] signerCertificateChain;
/** The callback handler to use when needing to interact with user. */
private CallbackHandler handler;
+ /** The command line parser. */
+ private ToolParser cmdLineParser;
+ protected ArrayList fileAndAlias = new ArrayList();;
private Main()
{
@@ -126,10 +134,12 @@ public class Main
log.entering(Main.class.getName(), "main", args); //$NON-NLS-1$
Main tool = new Main();
+ int result = 1;
try
{
tool.processArgs(args);
tool.start();
+ result = 0;
}
catch (SecurityException x)
{
@@ -141,11 +151,13 @@ public class Main
log.throwing(Main.class.getName(), "main", x); //$NON-NLS-1$
System.err.println(Messages.getString("Main.9") + x); //$NON-NLS-1$
}
+ finally
+ {
+ tool.teardown();
+ }
- tool.teardown();
-
- log.exiting(Main.class.getName(), "main"); //$NON-NLS-1$
- // System.exit(0);
+ log.exiting(Main.class.getName(), "main", Integer.valueOf(result)); //$NON-NLS-1$
+ System.exit(result);
}
// helper methods -----------------------------------------------------------
@@ -155,65 +167,15 @@ public class Main
* preparation for the user desired action.
*
* @param args an array of options (strings).
- * @throws Exception if an exceptio occurs during the process.
+ * @throws Exception if an exception occurs during the process.
*/
private void processArgs(String[] args) throws Exception
{
log.entering(this.getClass().getName(), "processArgs", args); //$NON-NLS-1$
- HelpPrinter.checkHelpKey(args, HELP_PATH);
- if (args == null || args.length == 0)
- HelpPrinter.printHelpAndExit(HELP_PATH);
-
- int limit = args.length;
- log.finest("args.length=" + limit); //$NON-NLS-1$
- int i = 0;
- String opt;
- while (i < limit)
- {
- opt = args[i++];
- log.finest("args[" + (i - 1) + "]=" + opt); //$NON-NLS-1$ //$NON-NLS-2$
- if (opt == null || opt.length() == 0)
- continue;
-
- if ("-verify".equals(opt)) // -verify //$NON-NLS-1$
- verify = true;
- else if ("-keystore".equals(opt)) // -keystore URL //$NON-NLS-1$
- ksURL = args[i++];
- else if ("-storetype".equals(opt)) // -storetype STORE_TYPE //$NON-NLS-1$
- ksType = args[i++];
- else if ("-storepass".equals(opt)) // -storepass PASSWORD //$NON-NLS-1$
- ksPassword = args[i++];
- else if ("-keypass".equals(opt)) // -keypass PASSWORD //$NON-NLS-1$
- password = args[i++];
- else if ("-sigfile".equals(opt)) // -sigfile NAME //$NON-NLS-1$
- sigFileName = args[i++];
- else if ("-signedjar".equals(opt)) // -signedjar FILE_NAME //$NON-NLS-1$
- signedJarFileName = args[i++];
- else if ("-verbose".equals(opt)) // -verbose //$NON-NLS-1$
- verbose = true;
- else if ("-certs".equals(opt)) // -certs //$NON-NLS-1$
- certs = true;
- else if ("-internalsf".equals(opt)) // -internalsf //$NON-NLS-1$
- internalSF = true;
- else if ("-sectionsonly".equals(opt)) // -sectionsonly //$NON-NLS-1$
- sectionsOnly = true;
- else if ("-provider".equals(opt)) // -provider PROVIDER_CLASS_NAME //$NON-NLS-1$
- providerClassName = args[i++];
- else
- {
- jarFileName = opt;
- if (! verify)
- alias = args[i++];
-
- break;
- }
- }
-
- if (i < limit) // more options than needed
- log.fine("Last argument is assumed at index #" + (i - 1) //$NON-NLS-1$
- + ". Remaining arguments (" + args[i] //$NON-NLS-1$
- + "...) will be ignored"); //$NON-NLS-1$
+ cmdLineParser = new ToolParser();
+ cmdLineParser.initializeParser();
+ cmdLineParser.parse(args, new ToolParserCallback());
setupCommonParams();
if (verify)
@@ -319,9 +281,6 @@ public class Main
{
log.entering(this.getClass().getName(), "setupCommonParams"); //$NON-NLS-1$
- if (jarFileName == null)
- HelpPrinter.printHelpAndExit(HELP_PATH);
-
File jar = new File(jarFileName);
if (! jar.exists())
throw new FileNotFoundException(jarFileName);
@@ -429,9 +388,6 @@ public class Main
InputStream stream = url.openStream();
store.load(stream, ksPasswordChars);
- if (alias == null)
- HelpPrinter.printHelpAndExit(HELP_PATH);
-
if (! store.containsAlias(alias))
throw new SecurityException(Messages.getFormattedString("Main.6", alias)); //$NON-NLS-1$
@@ -564,4 +520,155 @@ public class Main
return handler;
}
+
+ private class ToolParserCallback
+ extends FileArgumentCallback
+ {
+ public void notifyFile(String fileArgument)
+ {
+ fileAndAlias.add(fileArgument);
+ }
+ }
+
+ private class ToolParser
+ extends ClasspathToolParser
+ {
+ public ToolParser()
+ {
+ super(KEYTOOL_TOOL, true);
+ }
+
+ protected void validate() throws OptionException
+ {
+ if (fileAndAlias.size() < 1)
+ throw new OptionException(Messages.getString("Main.133")); //$NON-NLS-1$
+
+ jarFileName = (String) fileAndAlias.get(0);
+ if (! verify) // must have an ALIAS. use "mykey" if undefined
+ if (fileAndAlias.size() < 2)
+ {
+ log.finer("Missing ALIAS argument. Will use [mykey] instead"); //$NON-NLS-1$
+ alias = "mykey"; //$NON-NLS-1$
+ }
+ else
+ alias = (String) fileAndAlias.get(1);
+ }
+
+ public void initializeParser()
+ {
+ setHeader(Messages.getString("Main.2")); //$NON-NLS-1$
+ setFooter(Messages.getString("Main.1")); //$NON-NLS-1$
+ OptionGroup signGroup = new OptionGroup(Messages.getString("Main.0")); //$NON-NLS-1$
+ signGroup.add(new Option("keystore", //$NON-NLS-1$
+ Messages.getString("Main.101"), //$NON-NLS-1$
+ Messages.getString("Main.102")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ ksURL = argument;
+ }
+ });
+ signGroup.add(new Option("storetype", //$NON-NLS-1$
+ Messages.getString("Main.104"), //$NON-NLS-1$
+ Messages.getString("Main.105")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ ksType = argument;
+ }
+ });
+ signGroup.add(new Option("storepass", //$NON-NLS-1$
+ Messages.getString("Main.107"), //$NON-NLS-1$
+ Messages.getString("Main.108")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ ksPassword = argument;
+ }
+ });
+ signGroup.add(new Option("keypass", //$NON-NLS-1$
+ Messages.getString("Main.110"), //$NON-NLS-1$
+ Messages.getString("Main.111")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ password = argument;
+ }
+ });
+ signGroup.add(new Option("sigfile", //$NON-NLS-1$
+ Messages.getString("Main.113"), //$NON-NLS-1$
+ Messages.getString("Main.114")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ sigFileName = argument;
+ }
+ });
+ signGroup.add(new Option("signedjar", //$NON-NLS-1$
+ Messages.getString("Main.116"), //$NON-NLS-1$
+ Messages.getString("Main.117")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ signedJarFileName = argument;
+ }
+ });
+ add(signGroup);
+
+ OptionGroup verifyGroup = new OptionGroup(Messages.getString("Main.118")); //$NON-NLS-1$
+ verifyGroup.add(new Option("verify", //$NON-NLS-1$
+ Messages.getString("Main.120")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ verify = true;
+ }
+ });
+ verifyGroup.add(new Option("certs", //$NON-NLS-1$
+ Messages.getString("Main.122")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ certs = true;
+ }
+ });
+ add(verifyGroup);
+
+ OptionGroup commonGroup = new OptionGroup(Messages.getString("Main.123")); //$NON-NLS-1$
+ commonGroup.add(new Option("verbose", //$NON-NLS-1$
+ Messages.getString("Main.125")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ verbose = true;
+ }
+ });
+ commonGroup.add(new Option("internalsf", //$NON-NLS-1$
+ Messages.getString("Main.127")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ internalSF = true;
+ }
+ });
+ commonGroup.add(new Option("sectionsonly", //$NON-NLS-1$
+ Messages.getString("Main.129")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ sectionsOnly = true;
+ }
+ });
+ commonGroup.add(new Option("provider", //$NON-NLS-1$
+ Messages.getString("Main.131"), //$NON-NLS-1$
+ Messages.getString("Main.132")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ providerClassName = argument;
+ }
+ });
+ add(commonGroup);
+ }
+ }
}
diff --git a/tools/gnu/classpath/tools/jarsigner/Messages.java b/tools/gnu/classpath/tools/jarsigner/Messages.java
index 284639115..35f461669 100644
--- a/tools/gnu/classpath/tools/jarsigner/Messages.java
+++ b/tools/gnu/classpath/tools/jarsigner/Messages.java
@@ -54,7 +54,7 @@ import java.util.logging.Logger;
class Messages
{
private static final Logger log = Logger.getLogger(Messages.class.getName());
- private static final String BUNDLE_NAME = "gnu.classpath.tools.jarsigner.MessageBundle"; //$NON-NLS-1$
+ private static final String BUNDLE_NAME = "gnu.classpath.tools.jarsigner.messages";
private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME);
private static final Map CACHED_FORMATS = new HashMap(5);
@@ -88,7 +88,7 @@ class Messages
CACHED_FORMATS.put(key, mf);
}
- // if the argument is not an array, then build one consisiting of the
+ // if the argument is not an array, then build one consisting of the
// sole argument before passing it to the format() method
try
{
diff --git a/tools/gnu/classpath/tools/jarsigner/jarsigner.txt b/tools/gnu/classpath/tools/jarsigner/jarsigner.txt
deleted file mode 100644
index e615609c1..000000000
--- a/tools/gnu/classpath/tools/jarsigner/jarsigner.txt
+++ /dev/null
@@ -1,116 +0,0 @@
-NAME
- jarsigner - Java ARchive (JAR) file signing and verification tool
-
-SYNOPSIS
- jarsigner [OPTION]... FILE ALIAS
- jarsigner -verify [OPTION]... FILE
-
-DESCRIPTION
- When the first form is used, the tool signs the designated JAR file.
- The second form, on the other hand, is used to verify a previously
- signed JAR file.
-
- FILE is the .JAR file to process; i.e. to sign if the first syntax form
- is used, or to verify if the second syntax form is used instead.
-
- ALIAS must be a known Alias of a Key Entry in the designated key store.
- The private key material associated with this Alias is then used for
- signing the designated .JAR file.
-
-SIGNING OPTIONS
- -keystore URL
- Use this option to specify the location of the key store to use.
- The default value is a file URL referencing the file named
- ".keystore" (all lower case and without the enclosing quotes)
- located in the path returned by the call to
- java.lang.System#getProperty(String) using "user.home" as
- argument.
-
- If a URL was specified, but was found to be malformed --e.g.
- missing protocol element-- the tool will attempt to use the URL
- value as a file-name (with absolute or relative path-name) of a
- key store --as if the protocol was "file:".
-
- -storetype STORE_TYPE
- Use this option to specify the type of the key store to use.
- The default value, if this option is omitted, is that of the
- property "keystore.type" in the security properties file, which
- is obtained by invoking the static method call getDefaultType()
- in java.security.KeyStore.
-
- -storepass PASSWORD
- Use this option to specify the password which will be used to
- unlock the key store. If this option is missing, the User will
- be prompted to provide a password.
-
- -keypass PASSWORD
- Use this option to specify the password which the tool will use
- to unlock the Key Entry associated with the designated Alias.
-
- If this option is omitted, the tool will first attempt to unlock
- the Key Entry using the same password protecting the key store.
- If this fails, you will then be prompted to provide a password.
-
- -sigfile NAME
- Use this option to designate a literal that will be used to
- construct file names for both the .SF and .DSA signature files.
- These files will be generated, by the tool, and placed in the
- META-INF directory of the signed JAR. Permissible characters
- for NAME must be in the range "a-zA-Z0-9_-". All characters
- will be converted to upper-case ones.
-
- If this option is missing, the first eight characters of the
- ALIAS argument will be used. When this is the case, any
- character in ALIAS that is outside the permissible range of
- characters will be replaced by an underscore.
-
- -signedjar FILE_NAME
- Use this option to specify the file name of the signed JAR. If
- this option is omitted, then the signed JAR will be named the
- same as FILE; i.e. the input JAR file will be replaced with the
- signed copy.
-
-VERIFICATION OPTIONS
- -verify
- Use this option to indicate that the tool is to be used for
- verification purposes.
-
- -certs This option is used in conjunction with the -verbose option.
- When present, along with the -verbose option, the tool will
- print more detailed information about the certificates of the
- signer(s) being processed.
-
-COMMON OPTIONS
- -verbose
- Use this option to force the tool to generate more verbose
- messages, during its processing.
-
- -internalsf
- When present, the tool will include --which otherwise it does
- not-- the .SF file in the .DSA generated file.
-
- -sectionsonly
- When present, the tool will include in the .SF generated file
- --which otherwise it does not-- a header containing a hash of
- the whole manifest file. When that header is included, the
- tool can quickly check, during verification, if the hash (in
- the header) matches or not the manifest file.
-
- -provider PROVIDER_CLASS_NAME
- A fully qualified class name of a Security Provider to add to
- the current list of Security Providers already installed in the
- JVM in-use. If a provider class is specified with this option,
- and was successfully added to the runtime --i.e. it was not
- already installed-- then the tool will attempt to remove this
- Security Provider before exiting.
-
- -help Prints this help text.
-
-REPORTING BUGS
- Please report bugs at http://www.gnu.org/software/classpath/bugs.html
-
-COPYRIGHT
- Copyright (C) 2006 Free Software Foundation, Inc.
- This is free software; see the source for copying conditions. There is
- NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE.
diff --git a/tools/gnu/classpath/tools/keytool/CertReqCmd.java b/tools/gnu/classpath/tools/keytool/CertReqCmd.java
index 0c64246e8..fc85e6abd 100644
--- a/tools/gnu/classpath/tools/keytool/CertReqCmd.java
+++ b/tools/gnu/classpath/tools/keytool/CertReqCmd.java
@@ -38,6 +38,11 @@ exception statement from your version. */
package gnu.classpath.tools.keytool;
+import gnu.classpath.tools.getopt.ClasspathToolParser;
+import gnu.classpath.tools.getopt.Option;
+import gnu.classpath.tools.getopt.OptionException;
+import gnu.classpath.tools.getopt.OptionGroup;
+import gnu.classpath.tools.getopt.Parser;
import gnu.java.security.OID;
import gnu.java.security.der.BitString;
import gnu.java.security.der.DER;
@@ -123,7 +128,7 @@ import javax.security.auth.x500.X500Principal;
*
* <dt>-keypass PASSWORD</dt>
*
- * <dt>-storetype STORE_TYP}</dt>
+ * <dt>-storetype STORE_TYPE</dt>
* <dd>Use this option to specify the type of the key store to use. The
* default value, if this option is omitted, is that of the property
* <code>keystore.type</code> in the security properties file, which is
@@ -170,15 +175,16 @@ import javax.security.auth.x500.X500Principal;
class CertReqCmd extends Command
{
private static final Logger log = Logger.getLogger(CertReqCmd.class.getName());
- private String _alias;
- private String _sigAlgorithm;
- private String _certReqFileName;
- private String _password;
- private String _ksType;
- private String _ksURL;
- private String _ksPassword;
- private String _providerClassName;
- private boolean nullAttributes;
+ private static final String ATTRIBUTES_OPT = "attributes"; //$NON-NLS-1$
+ protected String _alias;
+ protected String _sigAlgorithm;
+ protected String _certReqFileName;
+ protected String _password;
+ protected String _ksType;
+ protected String _ksURL;
+ protected String _ksPassword;
+ protected String _providerClassName;
+ protected boolean nullAttributes;
// default 0-arguments constructor
@@ -246,60 +252,19 @@ class CertReqCmd extends Command
// life-cycle methods -------------------------------------------------------
- int processArgs(String[] args, int i)
- {
- int limit = args.length;
- String opt;
- while (++i < limit)
- {
- opt = args[i];
- log.finest("args[" + i + "]=" + opt); //$NON-NLS-1$ //$NON-NLS-2$
- if (opt == null || opt.length() == 0)
- continue;
-
- if ("-alias".equals(opt)) // -alias ALIAS //$NON-NLS-1$
- _alias = args[++i];
- else if ("-sigalg".equals(opt)) // -sigalg ALGORITHM //$NON-NLS-1$
- _sigAlgorithm = args[++i];
- else if ("-file".equals(opt)) // -file FILE_NAME //$NON-NLS-1$
- _certReqFileName = args[++i];
- else if ("-keypass".equals(opt)) // -keypass PASSWORD //$NON-NLS-1$
- _password = args[++i];
- else if ("-storetype".equals(opt)) // -storetype STORE_TYPE //$NON-NLS-1$
- _ksType = args[++i];
- else if ("-keystore".equals(opt)) // -keystore URL //$NON-NLS-1$
- _ksURL = args[++i];
- else if ("-storepass".equals(opt)) // -storepass PASSWORD //$NON-NLS-1$
- _ksPassword = args[++i];
- else if ("-provider".equals(opt)) // -provider PROVIDER_CLASS_NAME //$NON-NLS-1$
- _providerClassName = args[++i];
- else if ("-v".equals(opt)) //$NON-NLS-1$
- verbose = true;
- else if ("-attributes".equals(opt)) //$NON-NLS-1$
- nullAttributes = true;
- else
- break;
- }
-
- return i;
- }
-
void setup() throws Exception
{
setOutputStreamParam(_certReqFileName);
setKeyStoreParams(_providerClassName, _ksType, _ksPassword, _ksURL);
setAliasParam(_alias);
setKeyPasswordNoPrompt(_password);
-// setSignatureAlgorithm(_sigAlgorithm);
log.finer("-certreq handler will use the following options:"); //$NON-NLS-1$
log.finer(" -alias=" + alias); //$NON-NLS-1$
log.finer(" -sigalg=" + _sigAlgorithm); //$NON-NLS-1$
log.finer(" -file=" + _certReqFileName); //$NON-NLS-1$
- log.finer(" -keypass=" + _password); //$NON-NLS-1$
log.finer(" -storetype=" + storeType); //$NON-NLS-1$
log.finer(" -keystore=" + storeURL); //$NON-NLS-1$
- log.finer(" -storepass=" + String.valueOf(storePasswordChars)); //$NON-NLS-1$
log.finer(" -provider=" + provider); //$NON-NLS-1$
log.finer(" -v=" + verbose); //$NON-NLS-1$
log.finer(" -attributes=" + nullAttributes); //$NON-NLS-1$
@@ -346,6 +311,108 @@ class CertReqCmd extends Command
// own methods --------------------------------------------------------------
+ Parser getParser()
+ {
+ log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$
+
+ Parser result = new ClasspathToolParser(Main.CERTREQ_CMD, true);
+ result.setHeader(Messages.getString("CertReqCmd.25")); //$NON-NLS-1$
+ result.setFooter(Messages.getString("CertReqCmd.24")); //$NON-NLS-1$
+ OptionGroup options = new OptionGroup(Messages.getString("CertReqCmd.23")); //$NON-NLS-1$
+ options.add(new Option(Main.ALIAS_OPT,
+ Messages.getString("CertReqCmd.22"), //$NON-NLS-1$
+ Messages.getString("CertReqCmd.21")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _alias = argument;
+ }
+ });
+ options.add(new Option(Main.SIGALG_OPT,
+ Messages.getString("CertReqCmd.20"), //$NON-NLS-1$
+ Messages.getString("CertReqCmd.19")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _sigAlgorithm = argument;
+ }
+ });
+ options.add(new Option(Main.FILE_OPT,
+ Messages.getString("CertReqCmd.18"), //$NON-NLS-1$
+ Messages.getString("CertReqCmd.17")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _certReqFileName = argument;
+ }
+ });
+ options.add(new Option(Main.KEYPASS_OPT,
+ Messages.getString("CertReqCmd.16"), //$NON-NLS-1$
+ Messages.getString("CertReqCmd.9")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _password = argument;
+ }
+ });
+ options.add(new Option(Main.STORETYPE_OPT,
+ Messages.getString("CertReqCmd.14"), //$NON-NLS-1$
+ Messages.getString("CertReqCmd.13")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksType = argument;
+ }
+ });
+ options.add(new Option(Main.KEYSTORE_OPT,
+ Messages.getString("CertReqCmd.12"), //$NON-NLS-1$
+ Messages.getString("CertReqCmd.11")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksURL = argument;
+ }
+ });
+ options.add(new Option(Main.STOREPASS_OPT,
+ Messages.getString("CertReqCmd.10"), //$NON-NLS-1$
+ Messages.getString("CertReqCmd.9")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksPassword = argument;
+ }
+ });
+ options.add(new Option(Main.PROVIDER_OPT,
+ Messages.getString("CertReqCmd.8"), //$NON-NLS-1$
+ Messages.getString("CertReqCmd.7")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _providerClassName = argument;
+ }
+ });
+ options.add(new Option(Main.VERBOSE_OPT,
+ Messages.getString("CertReqCmd.6")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ verbose = true;
+ }
+ });
+ options.add(new Option(ATTRIBUTES_OPT,
+ Messages.getString("CertReqCmd.5")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ nullAttributes = true;
+ }
+ });
+ result.add(options);
+
+ log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$
+ return result;
+ }
+
/**
* @param aliasName
* @param publicKey
diff --git a/tools/gnu/classpath/tools/keytool/Command.java b/tools/gnu/classpath/tools/keytool/Command.java
index a59614644..0811074b8 100644
--- a/tools/gnu/classpath/tools/keytool/Command.java
+++ b/tools/gnu/classpath/tools/keytool/Command.java
@@ -42,6 +42,7 @@ import gnu.classpath.SystemProperties;
import gnu.classpath.tools.common.CallbackUtil;
import gnu.classpath.tools.common.ProviderUtil;
import gnu.classpath.tools.common.SecurityProviderInfo;
+import gnu.classpath.tools.getopt.Parser;
import gnu.java.security.OID;
import gnu.java.security.Registry;
import gnu.java.security.der.BitString;
@@ -167,10 +168,17 @@ abstract class Command
private int providerNdx = -2;
/** The callback handler to use when needing to interact with user. */
private CallbackHandler handler;
+ /** The shutdown hook. */
+ private ShutdownHook shutdownThread;
// Constructor(s) -----------------------------------------------------------
- // default 0-arguments constructor
+ protected Command()
+ {
+ super();
+ shutdownThread = new ShutdownHook();
+ Runtime.getRuntime().addShutdownHook(shutdownThread);
+ }
// Methods ------------------------------------------------------------------
@@ -193,14 +201,16 @@ abstract class Command
public void doCommand() throws Exception
{
try
- {
- setup();
- start();
- }
+ {
+ setup();
+ start();
+ }
finally
- {
- teardown();
- }
+ {
+ teardown();
+ if (shutdownThread != null)
+ Runtime.getRuntime().removeShutdownHook(shutdownThread);
+ }
}
/**
@@ -228,11 +238,18 @@ abstract class Command
*
* @param args an array of options for this handler and possibly other
* commands and their options.
- * @param startIndex the index of the first argument in <code>args</code> to
- * process.
- * @return the index of the first unprocessed argument in <code>args</code>.
+ * @return the remaining un-processed <code>args</code>.
*/
- abstract int processArgs(String[] args, int startIndex);
+ String[] processArgs(String[] args)
+ {
+ log.entering(this.getClass().getName(), "processArgs", args); //$NON-NLS-1$
+
+ Parser cmdOptionsParser = getParser();
+ String[] result = cmdOptionsParser.parse(args);
+
+ log.exiting(this.getClass().getName(), "processArgs", result); //$NON-NLS-1$
+ return result;
+ }
/**
* Initialize this concrete command handler for later invocation of the
@@ -346,6 +363,12 @@ abstract class Command
// parameter setup and validation methods -----------------------------------
/**
+ * @return a {@link Parser} that knows how to parse the concrete command's
+ * options.
+ */
+ abstract Parser getParser();
+
+ /**
* Convenience method to setup the key store given its type, its password, its
* location and portentially a specialized security provider.
*
@@ -486,7 +509,6 @@ abstract class Command
storePasswordChars = pcb.getPassword();
pcb.clearPassword();
}
- log.finest("storePasswordChars = [" + String.valueOf(storePasswordChars)+ "]"); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
@@ -575,7 +597,7 @@ abstract class Command
catch (IOException x)
{
log.fine("Exception while closing the key store input stream: " + x //$NON-NLS-1$
- + ". Ignore"); //$NON-NLS-1$
+ + ". Ignore"); //$NON-NLS-1$
}
}
@@ -970,7 +992,7 @@ abstract class Command
protected void saveKeyStore(char[] password) throws IOException,
KeyStoreException, NoSuchAlgorithmException, CertificateException
{
- log.entering(this.getClass().getName(), "saveKeyStore", String.valueOf(password)); //$NON-NLS-1$
+ log.entering(this.getClass().getName(), "saveKeyStore"); //$NON-NLS-1$
URLConnection con = storeURL.openConnection();
con.setDoOutput(true);
@@ -1144,4 +1166,15 @@ abstract class Command
return handler;
}
+
+ // Inner class(es) ==========================================================
+
+ private class ShutdownHook
+ extends Thread
+ {
+ public void run()
+ {
+ teardown();
+ }
+ }
}
diff --git a/tools/gnu/classpath/tools/keytool/DeleteCmd.java b/tools/gnu/classpath/tools/keytool/DeleteCmd.java
index 968af50f8..4c32ee1e6 100644
--- a/tools/gnu/classpath/tools/keytool/DeleteCmd.java
+++ b/tools/gnu/classpath/tools/keytool/DeleteCmd.java
@@ -38,6 +38,12 @@ exception statement from your version. */
package gnu.classpath.tools.keytool;
+import gnu.classpath.tools.getopt.ClasspathToolParser;
+import gnu.classpath.tools.getopt.Option;
+import gnu.classpath.tools.getopt.OptionException;
+import gnu.classpath.tools.getopt.OptionGroup;
+import gnu.classpath.tools.getopt.Parser;
+
import java.io.IOException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
@@ -64,7 +70,7 @@ import javax.security.auth.callback.UnsupportedCallbackException;
* omitted from the command line.
* <p></dd>
*
- * <dt>-storetype STORE_TYP}</dt>
+ * <dt>-storetype STORE_TYPE</dt>
* <dd>Use this option to specify the type of the key store to use. The
* default value, if this option is omitted, is that of the property
* <code>keystore.type</code> in the security properties file, which is
@@ -106,11 +112,11 @@ import javax.security.auth.callback.UnsupportedCallbackException;
class DeleteCmd extends Command
{
private static final Logger log = Logger.getLogger(DeleteCmd.class.getName());
- private String _alias;
- private String _ksType;
- private String _ksURL;
- private String _ksPassword;
- private String _providerClassName;
+ protected String _alias;
+ protected String _ksType;
+ protected String _ksURL;
+ protected String _ksPassword;
+ protected String _providerClassName;
// default 0-arguments constructor
@@ -148,36 +154,6 @@ class DeleteCmd extends Command
// life-cycle methods -------------------------------------------------------
- int processArgs(String[] args, int i)
- {
- int limit = args.length;
- String opt;
- while (++i < limit)
- {
- opt = args[i];
- log.finest("args[" + i + "]=" + opt); //$NON-NLS-1$ //$NON-NLS-2$
- if (opt == null || opt.length() == 0)
- continue;
-
- if ("-alias".equals(opt)) // -alias ALIAS //$NON-NLS-1$
- _alias = args[++i];
- else if ("-storetype".equals(opt)) // -storetype STORE_TYPE //$NON-NLS-1$
- _ksType = args[++i];
- else if ("-keystore".equals(opt)) // -keystore URL //$NON-NLS-1$
- _ksURL = args[++i];
- else if ("-storepass".equals(opt)) // -storepass PASSWORD //$NON-NLS-1$
- _ksPassword = args[++i];
- else if ("-provider".equals(opt)) // -provider PROVIDER_CLASS_NAME //$NON-NLS-1$
- _providerClassName = args[++i];
- else if ("-v".equals(opt)) //$NON-NLS-1$
- verbose = true;
- else
- break;
- }
-
- return i;
- }
-
void setup() throws Exception
{
setKeyStoreParams(_providerClassName, _ksType, _ksPassword, _ksURL);
@@ -187,7 +163,6 @@ class DeleteCmd extends Command
log.finer(" -alias=" + alias); //$NON-NLS-1$
log.finer(" -storetype=" + storeType); //$NON-NLS-1$
log.finer(" -keystore=" + storeURL); //$NON-NLS-1$
- log.finer(" -storepass=" + String.valueOf(storePasswordChars)); //$NON-NLS-1$
log.finer(" -provider=" + provider); //$NON-NLS-1$
log.finer(" -v=" + verbose); //$NON-NLS-1$
}
@@ -206,6 +181,73 @@ class DeleteCmd extends Command
// own methods --------------------------------------------------------------
+ Parser getParser()
+ {
+ log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$
+
+ Parser result = new ClasspathToolParser(Main.DELETE_CMD, true);
+ result.setHeader(Messages.getString("DeleteCmd.18")); //$NON-NLS-1$
+ result.setFooter(Messages.getString("DeleteCmd.17")); //$NON-NLS-1$
+ OptionGroup options = new OptionGroup(Messages.getString("DeleteCmd.16")); //$NON-NLS-1$
+ options.add(new Option(Main.ALIAS_OPT,
+ Messages.getString("DeleteCmd.15"), //$NON-NLS-1$
+ Messages.getString("DeleteCmd.14")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _alias = argument;
+ }
+ });
+ options.add(new Option(Main.STORETYPE_OPT,
+ Messages.getString("DeleteCmd.13"), //$NON-NLS-1$
+ Messages.getString("DeleteCmd.12")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksType = argument;
+ }
+ });
+ options.add(new Option(Main.KEYSTORE_OPT,
+ Messages.getString("DeleteCmd.11"), //$NON-NLS-1$
+ Messages.getString("DeleteCmd.10")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksURL = argument;
+ }
+ });
+ options.add(new Option(Main.STOREPASS_OPT,
+ Messages.getString("DeleteCmd.9"), //$NON-NLS-1$
+ Messages.getString("DeleteCmd.8")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksPassword = argument;
+ }
+ });
+ options.add(new Option(Main.PROVIDER_OPT,
+ Messages.getString("DeleteCmd.7"), //$NON-NLS-1$
+ Messages.getString("DeleteCmd.6")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _providerClassName = argument;
+ }
+ });
+ options.add(new Option(Main.VERBOSE_OPT,
+ Messages.getString("DeleteCmd.5")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ verbose = true;
+ }
+ });
+ result.add(options);
+
+ log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$
+ return result;
+ }
+
/**
* Set the alias to delete from the key store.
* <p>
diff --git a/tools/gnu/classpath/tools/keytool/ExportCmd.java b/tools/gnu/classpath/tools/keytool/ExportCmd.java
index c1c0d4f83..46f7acdf0 100644
--- a/tools/gnu/classpath/tools/keytool/ExportCmd.java
+++ b/tools/gnu/classpath/tools/keytool/ExportCmd.java
@@ -38,6 +38,11 @@ exception statement from your version. */
package gnu.classpath.tools.keytool;
+import gnu.classpath.tools.getopt.ClasspathToolParser;
+import gnu.classpath.tools.getopt.Option;
+import gnu.classpath.tools.getopt.OptionException;
+import gnu.classpath.tools.getopt.OptionGroup;
+import gnu.classpath.tools.getopt.Parser;
import gnu.java.security.util.Base64;
import java.io.IOException;
@@ -69,7 +74,7 @@ import java.util.logging.Logger;
* exported to. If omitted, STDOUT will be used instead.
* <p></dd>
*
- * <dt>-storetype STORE_TYP}</dt>
+ * <dt>-storetype STORE_TYPE</dt>
* <dd>Use this option to specify the type of the key store to use. The
* default value, if this option is omitted, is that of the property
* <code>keystore.type</code> in the security properties file, which is
@@ -119,13 +124,13 @@ import java.util.logging.Logger;
class ExportCmd extends Command
{
private static final Logger log = Logger.getLogger(ExportCmd.class.getName());
- private String _alias;
- private String _certFileName;
- private String _ksType;
- private String _ksURL;
- private String _ksPassword;
- private String _providerClassName;
- private boolean rfc;
+ protected String _alias;
+ protected String _certFileName;
+ protected String _ksType;
+ protected String _ksURL;
+ protected String _ksPassword;
+ protected String _providerClassName;
+ protected boolean rfc;
// default 0-arguments constructor
@@ -178,72 +183,37 @@ class ExportCmd extends Command
// life-cycle methods -------------------------------------------------------
- int processArgs(String[] args, int i)
- {
- int limit = args.length;
- String opt;
- while (++i < limit)
- {
- opt = args[i];
- log.finest("args[" + i + "]=" + opt);
- if (opt == null || opt.length() == 0)
- continue;
-
- if ("-alias".equals(opt)) // -alias ALIAS
- _alias = args[++i];
- else if ("-file".equals(opt)) // -file FILE_NAME
- _certFileName = args[++i];
- else if ("-storetype".equals(opt)) // -storetype STORE_TYPE
- _ksType = args[++i];
- else if ("-keystore".equals(opt)) // -keystore URL
- _ksURL = args[++i];
- else if ("-storepass".equals(opt)) // -storepass PASSWORD
- _ksPassword = args[++i];
- else if ("-provider".equals(opt)) // -provider PROVIDER_CLASS_NAME
- _providerClassName = args[++i];
- else if ("-rfc".equals(opt))
- rfc = true;
- else if ("-v".equals(opt))
- verbose = true;
- else
- break;
- }
-
- return i;
- }
-
void setup() throws Exception
{
setOutputStreamParam(_certFileName);
setKeyStoreParams(_providerClassName, _ksType, _ksPassword, _ksURL);
setAliasParam(_alias);
- log.finer("-export handler will use the following options:");
- log.finer(" -alias=" + alias);
- log.finer(" -file=" + _certFileName);
- log.finer(" -storetype=" + storeType);
- log.finer(" -keystore=" + storeURL);
- log.finer(" -storepass=" + String.valueOf(storePasswordChars));
- log.finer(" -provider=" + provider);
- log.finer(" -rfc=" + rfc);
- log.finer(" -v=" + verbose);
+ log.finer("-export handler will use the following options:"); //$NON-NLS-1$
+ log.finer(" -alias=" + alias); //$NON-NLS-1$
+ log.finer(" -file=" + _certFileName); //$NON-NLS-1$
+ log.finer(" -storetype=" + storeType); //$NON-NLS-1$
+ log.finer(" -keystore=" + storeURL); //$NON-NLS-1$
+ log.finer(" -provider=" + provider); //$NON-NLS-1$
+ log.finer(" -rfc=" + rfc); //$NON-NLS-1$
+ log.finer(" -v=" + verbose); //$NON-NLS-1$
}
void start() throws KeyStoreException, CertificateEncodingException,
IOException
{
- log.entering(this.getClass().getName(), "start");
+ log.entering(this.getClass().getName(), "start"); //$NON-NLS-1$
ensureStoreContainsAlias();
Certificate certificate;
if (store.isCertificateEntry(alias))
{
- log.fine("Alias [" + alias + "] is a trusted certificate");
+ log.finer("Alias [" + alias + "] is a trusted certificate"); //$NON-NLS-1$ //$NON-NLS-2$
certificate = store.getCertificate(alias);
}
else
{
- log.fine("Alias [" + alias + "] is a key entry");
+ log.finer("Alias [" + alias + "] is a key entry"); //$NON-NLS-1$ //$NON-NLS-2$
Certificate[] chain = store.getCertificateChain(alias);
certificate = chain[0];
}
@@ -253,14 +223,100 @@ class ExportCmd extends Command
{
String encoded = Base64.encode(derBytes, 0, derBytes.length, true);
PrintWriter pw = new PrintWriter(outStream, true);
- pw.println("-----BEGIN CERTIFICATE-----");
+ pw.println("-----BEGIN CERTIFICATE-----"); //$NON-NLS-1$
pw.println(encoded);
- pw.println("-----END CERTIFICATE-----");
+ pw.println("-----END CERTIFICATE-----"); //$NON-NLS-1$
}
else
outStream.write(derBytes);
// stream is closed in Command.teardown()
- log.exiting(this.getClass().getName(), "start");
+ log.exiting(this.getClass().getName(), "start"); //$NON-NLS-1$
+ }
+
+ // own methods --------------------------------------------------------------
+
+ Parser getParser()
+ {
+ log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$
+
+ Parser result = new ClasspathToolParser(Main.EXPORT_CMD, true);
+ result.setHeader(Messages.getString("ExportCmd.17")); //$NON-NLS-1$
+ result.setFooter(Messages.getString("ExportCmd.18")); //$NON-NLS-1$
+ OptionGroup options = new OptionGroup(Messages.getString("ExportCmd.19")); //$NON-NLS-1$
+ options.add(new Option(Main.ALIAS_OPT,
+ Messages.getString("ExportCmd.20"), //$NON-NLS-1$
+ Messages.getString("ExportCmd.21")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _alias = argument;
+ }
+ });
+ options.add(new Option(Main.FILE_OPT,
+ Messages.getString("ExportCmd.22"), //$NON-NLS-1$
+ Messages.getString("ExportCmd.23")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _certFileName = argument;
+ }
+ });
+ options.add(new Option(Main.STORETYPE_OPT,
+ Messages.getString("ExportCmd.24"), //$NON-NLS-1$
+ Messages.getString("ExportCmd.25")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksType = argument;
+ }
+ });
+ options.add(new Option(Main.KEYSTORE_OPT,
+ Messages.getString("ExportCmd.26"), //$NON-NLS-1$
+ Messages.getString("ExportCmd.27")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksURL = argument;
+ }
+ });
+ options.add(new Option(Main.STOREPASS_OPT,
+ Messages.getString("ExportCmd.28"), //$NON-NLS-1$
+ Messages.getString("ExportCmd.29")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksPassword = argument;
+ }
+ });
+ options.add(new Option(Main.PROVIDER_OPT,
+ Messages.getString("ExportCmd.30"), //$NON-NLS-1$
+ Messages.getString("ExportCmd.31")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _providerClassName = argument;
+ }
+ });
+ options.add(new Option(Main.RFC_OPT,
+ Messages.getString("ExportCmd.32")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ rfc = true;
+ }
+ });
+ options.add(new Option(Main.VERBOSE_OPT,
+ Messages.getString("ExportCmd.33")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ verbose = true;
+ }
+ });
+ result.add(options);
+
+ log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$
+ return result;
}
}
diff --git a/tools/gnu/classpath/tools/keytool/GenKeyCmd.java b/tools/gnu/classpath/tools/keytool/GenKeyCmd.java
index 2d92134c2..6da0f58b6 100644
--- a/tools/gnu/classpath/tools/keytool/GenKeyCmd.java
+++ b/tools/gnu/classpath/tools/keytool/GenKeyCmd.java
@@ -38,6 +38,11 @@ exception statement from your version. */
package gnu.classpath.tools.keytool;
+import gnu.classpath.tools.getopt.ClasspathToolParser;
+import gnu.classpath.tools.getopt.Option;
+import gnu.classpath.tools.getopt.OptionException;
+import gnu.classpath.tools.getopt.OptionGroup;
+import gnu.classpath.tools.getopt.Parser;
import gnu.java.security.util.Util;
import gnu.java.security.x509.X500DistinguishedName;
@@ -153,7 +158,7 @@ import javax.security.auth.callback.UnsupportedCallbackException;
*
* <dt>-validity DAY_COUNT</dt>
*
- * <dt>-storetype STORE_TYP}</dt>
+ * <dt>-storetype STORE_TYPE</dt>
* <dd>Use this option to specify the type of the key store to use. The
* default value, if this option is omitted, is that of the property
* <code>keystore.type</code> in the security properties file, which is
@@ -198,19 +203,20 @@ class GenKeyCmd extends Command
/** Default key size in bits. */
private static final int DEFAULT_KEY_SIZE = 1024;
- private String _alias;
- private String _keyAlgorithm;
- private String _keySizeStr;
- private String _sigAlgorithm;
- private String _dName;
- private String _password;
- private String _validityStr;
- private String _ksType;
- private String _ksURL;
- private String _ksPassword;
- private String _providerClassName;
+ protected String _alias;
+ protected String _keyAlgorithm;
+ protected String _keySizeStr;
+ protected String _sigAlgorithm;
+ protected String _dName;
+ protected String _password;
+ protected String _validityStr;
+ protected String _ksType;
+ protected String _ksURL;
+ protected String _ksPassword;
+ protected String _providerClassName;
private int keySize;
private X500DistinguishedName distinguishedName;
+ private Parser cmdOptionsParser;
// default 0-arguments constructor
@@ -294,48 +300,6 @@ class GenKeyCmd extends Command
// life-cycle methods -------------------------------------------------------
- int processArgs(String[] args, int i)
- {
- int limit = args.length;
- String opt;
- while (++i < limit)
- {
- opt = args[i];
- log.finest("args[" + i + "]=" + opt); //$NON-NLS-1$ //$NON-NLS-2$
- if (opt == null || opt.length() == 0)
- continue;
-
- if ("-alias".equals(opt)) // -alias ALIAS //$NON-NLS-1$
- _alias = args[++i];
- else if ("-keyalg".equals(opt)) // -keyalg ALGORITHM //$NON-NLS-1$
- _keyAlgorithm = args[++i];
- else if ("-keysize".equals(opt)) // -keysize KEY_SIZE //$NON-NLS-1$
- _keySizeStr = args[++i];
- else if ("-sigalg".equals(opt)) // -sigalg ALGORITHM //$NON-NLS-1$
- _sigAlgorithm = args[++i];
- else if ("-dname".equals(opt)) // -dname NAME //$NON-NLS-1$
- _dName = args[++i];
- else if ("-keypass".equals(opt)) // -keypass PASSWORD //$NON-NLS-1$
- _password = args[++i];
- else if ("-validity".equals(opt)) // -validity DAY_COUNT //$NON-NLS-1$
- _validityStr = args[++i];
- else if ("-storetype".equals(opt)) // -storetype STORE_TYPE //$NON-NLS-1$
- _ksType = args[++i];
- else if ("-keystore".equals(opt)) // -keystore URL //$NON-NLS-1$
- _ksURL = args[++i];
- else if ("-storepass".equals(opt)) // -storepass PASSWORD //$NON-NLS-1$
- _ksPassword = args[++i];
- else if ("-provider".equals(opt)) // -provider PROVIDER_CLASS_NAME //$NON-NLS-1$
- _providerClassName = args[++i];
- else if ("-v".equals(opt)) //$NON-NLS-1$
- verbose = true;
- else
- break;
- }
-
- return i;
- }
-
void setup() throws Exception
{
setKeyStoreParams(_providerClassName, _ksType, _ksPassword, _ksURL);
@@ -352,11 +316,9 @@ class GenKeyCmd extends Command
log.finer(" -keysize=" + keySize); //$NON-NLS-1$
log.finer(" -sigalg=" + signatureAlgorithm.getAlgorithm()); //$NON-NLS-1$
log.finer(" -dname=" + distinguishedName); //$NON-NLS-1$
- log.finer(" -keypass=" + String.valueOf(keyPasswordChars)); //$NON-NLS-1$
log.finer(" -validity=" + validityInDays); //$NON-NLS-1$
log.finer(" -storetype=" + storeType); //$NON-NLS-1$
log.finer(" -keystore=" + storeURL); //$NON-NLS-1$
- log.finer(" -storepass=" + String.valueOf(storePasswordChars)); //$NON-NLS-1$
log.finer(" -provider=" + provider); //$NON-NLS-1$
log.finer(" -v=" + verbose); //$NON-NLS-1$
}
@@ -368,14 +330,14 @@ class GenKeyCmd extends Command
log.entering(this.getClass().getName(), "start"); //$NON-NLS-1$
// 1. generate a new key-pair
- log.fine("About to generate key-pair...");
+ log.finer("About to generate key-pair..."); //$NON-NLS-1$
keyPairGenerator.initialize(keySize);
KeyPair kp = keyPairGenerator.generateKeyPair();
PublicKey publicKey = kp.getPublic();
PrivateKey privateKey = kp.getPrivate();
// 2. generate a self-signed certificate
- log.fine("About to generate a self-signed certificate...");
+ log.finer("About to generate a self-signed certificate..."); //$NON-NLS-1$
byte[] derBytes = getSelfSignedCertificate(distinguishedName,
publicKey,
privateKey);
@@ -398,6 +360,127 @@ class GenKeyCmd extends Command
// own methods --------------------------------------------------------------
+ Parser getParser()
+ {
+ log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$
+
+ Parser result = new ClasspathToolParser(Main.GENKEY_CMD, true);
+ result.setHeader(Messages.getString("GenKeyCmd.57")); //$NON-NLS-1$
+ result.setFooter(Messages.getString("GenKeyCmd.58")); //$NON-NLS-1$
+ OptionGroup options = new OptionGroup(Messages.getString("GenKeyCmd.59")); //$NON-NLS-1$
+ options.add(new Option(Main.ALIAS_OPT,
+ Messages.getString("GenKeyCmd.60"), //$NON-NLS-1$
+ Messages.getString("GenKeyCmd.61")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _alias = argument;
+ }
+ });
+ options.add(new Option(Main.KEYALG_OPT,
+ Messages.getString("GenKeyCmd.62"), //$NON-NLS-1$
+ Messages.getString("GenKeyCmd.63")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _keyAlgorithm = argument;
+ }
+ });
+ options.add(new Option(Main.KEYSIZE_OPT,
+ Messages.getString("GenKeyCmd.64"), //$NON-NLS-1$
+ Messages.getString("GenKeyCmd.65")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _keySizeStr = argument;
+ }
+ });
+ options.add(new Option(Main.SIGALG_OPT,
+ Messages.getString("GenKeyCmd.66"), //$NON-NLS-1$
+ Messages.getString("GenKeyCmd.63")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _sigAlgorithm = argument;
+ }
+ });
+ options.add(new Option(Main.DNAME_OPT,
+ Messages.getString("GenKeyCmd.68"), //$NON-NLS-1$
+ Messages.getString("GenKeyCmd.69")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _dName = argument;
+ }
+ });
+ options.add(new Option(Main.KEYPASS_OPT,
+ Messages.getString("GenKeyCmd.70"), //$NON-NLS-1$
+ Messages.getString("GenKeyCmd.71")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _password = argument;
+ }
+ });
+ options.add(new Option(Main.VALIDITY_OPT,
+ Messages.getString("GenKeyCmd.72"), //$NON-NLS-1$
+ Messages.getString("GenKeyCmd.73")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _validityStr = argument;
+ }
+ });
+ options.add(new Option(Main.STORETYPE_OPT,
+ Messages.getString("GenKeyCmd.74"), //$NON-NLS-1$
+ Messages.getString("GenKeyCmd.75")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksType = argument;
+ }
+ });
+ options.add(new Option(Main.KEYSTORE_OPT,
+ Messages.getString("GenKeyCmd.76"), //$NON-NLS-1$
+ Messages.getString("GenKeyCmd.77")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksURL = argument;
+ }
+ });
+ options.add(new Option(Main.STOREPASS_OPT,
+ Messages.getString("GenKeyCmd.78"), //$NON-NLS-1$
+ Messages.getString("GenKeyCmd.71")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksPassword = argument;
+ }
+ });
+ options.add(new Option(Main.PROVIDER_OPT,
+ Messages.getString("GenKeyCmd.80"), //$NON-NLS-1$
+ Messages.getString("GenKeyCmd.81")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _providerClassName = argument;
+ }
+ });
+ options.add(new Option(Main.VERBOSE_OPT,
+ Messages.getString("GenKeyCmd.82")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ verbose = true;
+ }
+ });
+ result.add(options);
+
+ log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$
+ return result;
+ }
+
/**
* @param size the desired key size as a string.
* @throws NumberFormatException if the string does not represent a valid
diff --git a/tools/gnu/classpath/tools/keytool/IdentityDBCmd.java b/tools/gnu/classpath/tools/keytool/IdentityDBCmd.java
index cb6b6dac2..46c5b9769 100644
--- a/tools/gnu/classpath/tools/keytool/IdentityDBCmd.java
+++ b/tools/gnu/classpath/tools/keytool/IdentityDBCmd.java
@@ -38,6 +38,12 @@ exception statement from your version. */
package gnu.classpath.tools.keytool;
+import gnu.classpath.tools.getopt.ClasspathToolParser;
+import gnu.classpath.tools.getopt.Option;
+import gnu.classpath.tools.getopt.OptionException;
+import gnu.classpath.tools.getopt.OptionGroup;
+import gnu.classpath.tools.getopt.Parser;
+
import java.util.logging.Logger;
/**
@@ -55,7 +61,7 @@ import java.util.logging.Logger;
* option is omitted, the tool will process STDIN.
* <p></dd>
*
- * <dt>-storetype STORE_TYP}</dt>
+ * <dt>-storetype STORE_TYPE</dt>
* <dd>Use this option to specify the type of the key store to use. The
* default value, if this option is omitted, is that of the property
* <code>keystore.type</code> in the security properties file, which is
@@ -97,11 +103,11 @@ import java.util.logging.Logger;
class IdentityDBCmd extends Command
{
private static final Logger log = Logger.getLogger(IdentityDBCmd.class.getName());
- private String _idbFileName;
- private String _ksType;
- private String _ksURL;
- private String _ksPassword;
- private String _providerClassName;
+ protected String _idbFileName;
+ protected String _ksType;
+ protected String _ksURL;
+ protected String _ksPassword;
+ protected String _providerClassName;
// default 0-arguments constructor
@@ -139,47 +145,85 @@ class IdentityDBCmd extends Command
// life-cycle methods -------------------------------------------------------
- int processArgs(String[] args, int i)
+ void setup() throws Exception
{
- int limit = args.length;
- String opt;
- while (++i < limit)
- {
- opt = args[i];
- log.finest("args[" + i + "]=" + opt);
- if (opt == null || opt.length() == 0)
- continue;
-
- if ("-file".equals(opt)) // -file FILE_NAME
- _idbFileName = args[++i];
- else if ("-storetype".equals(opt)) // -storetype STORE_TYPE
- _ksType = args[++i];
- else if ("-keystore".equals(opt)) // -keystore URL
- _ksURL = args[++i];
- else if ("-storepass".equals(opt)) // -storepass PASSWORD
- _ksPassword = args[++i];
- else if ("-provider".equals(opt)) // -provider PROVIDER_CLASS_NAME
- _providerClassName = args[++i];
- else if ("-v".equals(opt))
- verbose = true;
- else
- break;
- }
+ setInputStreamParam(_idbFileName);
+ setKeyStoreParams(_providerClassName, _ksType, _ksPassword, _ksURL);
- return i;
+ log.finer("-identitydb handler will use the following options:"); //$NON-NLS-1$
+ log.finer(" -file=" + _idbFileName); //$NON-NLS-1$
+ log.finer(" -storetype=" + storeType); //$NON-NLS-1$
+ log.finer(" -keystore=" + storeURL); //$NON-NLS-1$
+ log.finer(" -provider=" + provider); //$NON-NLS-1$
+ log.finer(" -v=" + verbose); //$NON-NLS-1$
}
- void setup() throws Exception
+ // own methods --------------------------------------------------------------
+
+ Parser getParser()
{
- setInputStreamParam(_idbFileName);
- setKeyStoreParams(_providerClassName, _ksType, _ksPassword, _ksURL);
+ log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$
+
+ Parser result = new ClasspathToolParser(Main.IDENTITYDB_CMD, true);
+ result.setHeader(Messages.getString("IdentityDBCmd.7")); //$NON-NLS-1$
+ result.setFooter(Messages.getString("IdentityDBCmd.8")); //$NON-NLS-1$
+ OptionGroup options = new OptionGroup(Messages.getString("IdentityDBCmd.9")); //$NON-NLS-1$
+ options.add(new Option(Main.FILE_OPT,
+ Messages.getString("IdentityDBCmd.10"), //$NON-NLS-1$
+ Messages.getString("IdentityDBCmd.11")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _idbFileName = argument;
+ }
+ });
+ options.add(new Option(Main.STORETYPE_OPT,
+ Messages.getString("IdentityDBCmd.12"), //$NON-NLS-1$
+ Messages.getString("IdentityDBCmd.13")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksType = argument;
+ }
+ });
+ options.add(new Option(Main.KEYSTORE_OPT,
+ Messages.getString("IdentityDBCmd.14"), //$NON-NLS-1$
+ Messages.getString("IdentityDBCmd.15")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksURL = argument;
+ }
+ });
+ options.add(new Option(Main.STOREPASS_OPT,
+ Messages.getString("IdentityDBCmd.16"), //$NON-NLS-1$
+ Messages.getString("IdentityDBCmd.17")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksPassword = argument;
+ }
+ });
+ options.add(new Option(Main.PROVIDER_OPT,
+ Messages.getString("IdentityDBCmd.18"), //$NON-NLS-1$
+ Messages.getString("IdentityDBCmd.19")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _providerClassName = argument;
+ }
+ });
+ options.add(new Option(Main.VERBOSE_OPT,
+ Messages.getString("IdentityDBCmd.20")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ verbose = true;
+ }
+ });
+ result.add(options);
- log.finer("-identitydb handler will use the following options:");
- log.finer(" -file=" + _idbFileName);
- log.finer(" -storetype=" + storeType);
- log.finer(" -keystore=" + storeURL);
- log.finer(" -storepass=" + new String(storePasswordChars));
- log.finer(" -provider=" + provider);
- log.finer(" -v=" + verbose);
+ log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$
+ return result;
}
}
diff --git a/tools/gnu/classpath/tools/keytool/ImportCmd.java b/tools/gnu/classpath/tools/keytool/ImportCmd.java
index b5058b581..2e01bc0e4 100644
--- a/tools/gnu/classpath/tools/keytool/ImportCmd.java
+++ b/tools/gnu/classpath/tools/keytool/ImportCmd.java
@@ -39,6 +39,11 @@ exception statement from your version. */
package gnu.classpath.tools.keytool;
import gnu.classpath.SystemProperties;
+import gnu.classpath.tools.getopt.ClasspathToolParser;
+import gnu.classpath.tools.getopt.Option;
+import gnu.classpath.tools.getopt.OptionException;
+import gnu.classpath.tools.getopt.OptionGroup;
+import gnu.classpath.tools.getopt.Parser;
import gnu.java.security.x509.X509CertPath;
import java.io.FileInputStream;
@@ -47,6 +52,7 @@ import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
+import java.security.Principal;
import java.security.PublicKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertPathValidator;
@@ -57,11 +63,14 @@ import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.PKIXCertPathValidatorResult;
import java.security.cert.PKIXParameters;
+import java.security.cert.TrustAnchor;
+import java.security.cert.X509Certificate;
import java.security.interfaces.DSAParams;
import java.security.interfaces.DSAPublicKey;
import java.security.interfaces.RSAPublicKey;
import java.util.Collection;
import java.util.LinkedList;
+import java.util.ListIterator;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -139,7 +148,7 @@ import javax.security.auth.callback.UnsupportedCallbackException;
* should be considered when trying to establish chain-of-trusts.
* <p></dd>
*
- * <dt>-storetype STORE_TYP}</dt>
+ * <dt>-storetype STORE_TYPE</dt>
* <dd>Use this option to specify the type of the key store to use. The
* default value, if this option is omitted, is that of the property
* <code>keystore.type</code> in the security properties file, which is
@@ -181,17 +190,37 @@ import javax.security.auth.callback.UnsupportedCallbackException;
class ImportCmd extends Command
{
private static final Logger log = Logger.getLogger(ImportCmd.class.getName());
- private String _alias;
- private String _certFileName;
- private String _password;
- private boolean noPrompt;
- private boolean trustCACerts;
- private String _ksType;
- private String _ksURL;
- private String _ksPassword;
- private String _providerClassName;
+ private static final String GKR = "gkr"; //$NON-NLS-1$
+ private static final String JKS = "jks"; //$NON-NLS-1$
+ private static final String LIB = "lib"; //$NON-NLS-1$
+ private static final String SECURITY = "security"; //$NON-NLS-1$
+ private static final String CACERTS = "cacerts"; //$NON-NLS-1$
+ private static final String CACERTS_GKR = CACERTS + "." + GKR; //$NON-NLS-1$
+ protected String _alias;
+ protected String _certFileName;
+ protected String _password;
+ protected boolean noPrompt;
+ protected boolean trustCACerts;
+ protected String _ksType;
+ protected String _ksURL;
+ protected String _ksPassword;
+ protected String _providerClassName;
private CertificateFactory x509Factory;
private boolean imported;
+ /**
+ * Pathname to a GKR-type cacerts file to use when trustCACerts is true. This
+ * is usually a file named "cacerts.gkr" located in lib/security in the folder
+ * specified by the system-property "gnu.classpath.home".
+ */
+ private String gkrCaCertsPathName;
+ /**
+ * Pathname to a JKS-type cacerts file to use when trustCACerts is true. This
+ * is usually a file named "cacerts" located in lib/security in the folder
+ * specified by the system-property "java.home".
+ */
+ private String jksCaCertsPathName;
+ /** Alias self-signed certificate. used when importing certificate replies. */
+ private X509Certificate selfSignedCertificate;
// default 0-arguments constructor
@@ -259,44 +288,6 @@ class ImportCmd extends Command
// life-cycle methods -------------------------------------------------------
- int processArgs(String[] args, int i)
- {
- int limit = args.length;
- String opt;
- while (++i < limit)
- {
- opt = args[i];
- log.finest("args[" + i + "]=" + opt); //$NON-NLS-1$ //$NON-NLS-2$
- if (opt == null || opt.length() == 0)
- continue;
-
- if ("-alias".equals(opt)) // -alias ALIAS //$NON-NLS-1$
- _alias = args[++i];
- else if ("-file".equals(opt)) // -file FILE_NAME //$NON-NLS-1$
- _certFileName = args[++i];
- else if ("-keypass".equals(opt)) // -keypass PASSWORD //$NON-NLS-1$
- _password = args[++i];
- else if ("-noprompt".equals(opt)) //$NON-NLS-1$
- noPrompt = true;
- else if ("-trustcacerts".equals(opt)) //$NON-NLS-1$
- trustCACerts = true;
- else if ("-storetype".equals(opt)) // -storetype STORE_TYPE //$NON-NLS-1$
- _ksType = args[++i];
- else if ("-keystore".equals(opt)) // -keystore URL //$NON-NLS-1$
- _ksURL = args[++i];
- else if ("-storepass".equals(opt)) // -storepass PASSWORD //$NON-NLS-1$
- _ksPassword = args[++i];
- else if ("-provider".equals(opt)) // -provider PROVIDER_CLASS_NAME //$NON-NLS-1$
- _providerClassName = args[++i];
- else if ("-v".equals(opt)) //$NON-NLS-1$
- verbose = true;
- else
- break;
- }
-
- return i;
- }
-
void setup() throws Exception
{
setInputStreamParam(_certFileName);
@@ -307,12 +298,10 @@ class ImportCmd extends Command
log.finer("-import handler will use the following options:"); //$NON-NLS-1$
log.finer(" -alias=" + alias); //$NON-NLS-1$
log.finer(" -file=" + _certFileName); //$NON-NLS-1$
- log.finer(" -keypass=" + _password); //$NON-NLS-1$
log.finer(" -noprompt=" + noPrompt); //$NON-NLS-1$
log.finer(" -trustcacerts=" + trustCACerts); //$NON-NLS-1$
log.finer(" -storetype=" + storeType); //$NON-NLS-1$
log.finer(" -keystore=" + storeURL); //$NON-NLS-1$
- log.finer(" -storepass=" + String.valueOf(storePasswordChars)); //$NON-NLS-1$
log.finer(" -provider=" + provider); //$NON-NLS-1$
log.finer(" -v=" + verbose); //$NON-NLS-1$
}
@@ -323,6 +312,20 @@ class ImportCmd extends Command
{
log.entering(this.getClass().getName(), "start"); //$NON-NLS-1$
+ if (trustCACerts)
+ {
+ String fs = SystemProperties.getProperty("file.separator"); //$NON-NLS-1$
+ String classpathHome = SystemProperties.getProperty("gnu.classpath.home"); //$NON-NLS-1$
+ gkrCaCertsPathName = new StringBuilder(classpathHome).append(fs)
+ .append(LIB).append(fs)
+ .append(SECURITY).append(fs)
+ .append(CACERTS_GKR).toString();
+ String javaHome = SystemProperties.getProperty("java.home"); //$NON-NLS-1$
+ jksCaCertsPathName = new StringBuilder(javaHome).append(fs)
+ .append(LIB).append(fs)
+ .append(SECURITY).append(fs)
+ .append(CACERTS).toString();
+ }
x509Factory = CertificateFactory.getInstance("X.509"); //$NON-NLS-1$
// the alias will tell us whether we're dealing with
// a new trusted certificate or a certificate reply
@@ -339,6 +342,107 @@ class ImportCmd extends Command
// own methods --------------------------------------------------------------
+ Parser getParser()
+ {
+ log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$
+
+ Parser result = new ClasspathToolParser(Main.IMPORT_CMD, true);
+ result.setHeader(Messages.getString("ImportCmd.27")); //$NON-NLS-1$
+ result.setFooter(Messages.getString("ImportCmd.26")); //$NON-NLS-1$
+ OptionGroup options = new OptionGroup(Messages.getString("ImportCmd.25")); //$NON-NLS-1$
+ options.add(new Option(Main.ALIAS_OPT,
+ Messages.getString("ImportCmd.24"), //$NON-NLS-1$
+ Messages.getString("ImportCmd.23")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _alias = argument;
+ }
+ });
+ options.add(new Option(Main.FILE_OPT,
+ Messages.getString("ImportCmd.22"), //$NON-NLS-1$
+ Messages.getString("ImportCmd.21")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _certFileName = argument;
+ }
+ });
+ options.add(new Option(Main.KEYPASS_OPT,
+ Messages.getString("ImportCmd.20"), //$NON-NLS-1$
+ Messages.getString("ImportCmd.19")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _password = argument;
+ }
+ });
+ options.add(new Option("noprompt", //$NON-NLS-1$
+ Messages.getString("ImportCmd.18")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ noPrompt = true;
+ }
+ });
+ options.add(new Option("trustcacerts", //$NON-NLS-1$
+ Messages.getString("ImportCmd.17")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ trustCACerts = true;
+ }
+ });
+ options.add(new Option(Main.STORETYPE_OPT,
+ Messages.getString("ImportCmd.16"), //$NON-NLS-1$
+ Messages.getString("ImportCmd.15")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksType = argument;
+ }
+ });
+ options.add(new Option(Main.KEYSTORE_OPT,
+ Messages.getString("ImportCmd.14"), //$NON-NLS-1$
+ Messages.getString("ImportCmd.13")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksURL = argument;
+ }
+ });
+ options.add(new Option(Main.STOREPASS_OPT,
+ Messages.getString("ImportCmd.12"), //$NON-NLS-1$
+ Messages.getString("ImportCmd.11")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksPassword = argument;
+ }
+ });
+ options.add(new Option(Main.PROVIDER_OPT,
+ Messages.getString("ImportCmd.10"), //$NON-NLS-1$
+ Messages.getString("ImportCmd.9")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _providerClassName = argument;
+ }
+ });
+ options.add(new Option(Main.VERBOSE_OPT,
+ Messages.getString("ImportCmd.8")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ verbose = true;
+ }
+ });
+ result.add(options);
+
+ log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$
+ return result;
+ }
+
/**
* When importing a new trusted certificate, <i>alias</i> MUST NOT yet exist
* in the key store.
@@ -542,8 +646,8 @@ class ImportCmd extends Command
if (chain == null)
throw new IllegalArgumentException(Messages.getFormattedString("ImportCmd.37", //$NON-NLS-1$
alias));
- Certificate anchor = chain[0];
- PublicKey anchorPublicKey = anchor.getPublicKey();
+ selfSignedCertificate = (X509Certificate) chain[0];
+ PublicKey anchorPublicKey = selfSignedCertificate.getPublicKey();
PublicKey certPublicKey = certificate.getPublicKey();
boolean sameKey;
if (anchorPublicKey instanceof DSAPublicKey)
@@ -598,17 +702,54 @@ class ImportCmd extends Command
}
/**
- * @param chain
+ * Given a collection of certificates returned as a certificate-reply, this
+ * method sorts the certificates in the collection so that the <i>Issuer</i>
+ * of the certificate at position <code>i</code> is the <i>Subject</i> of
+ * the certificate at position <code>i + 1</code>.
+ * <p>
+ * This method uses <code>selfSignedCertificate</code> to discover the first
+ * certificate in the chain. The <i>Trust Anchor</i> of the chain; i.e. the
+ * self-signed CA certificate, if it exsits, will be discovered/established
+ * later by an appropriate <i>Certificate Path Validator</i>.
+ * <p>
+ * An exception is thrown if (a) no initial certificate is found in the
+ * designated collection which can be used as the start of the chain, or (b)
+ * if a chain can not be constructed using all the certificates in the
+ * designated collection.
+ *
+ * @param chain a collection of certificates, not necessarily ordered, but
+ * assumed to include a CA certificate authenticating our alias
+ * public key, which is the subject of the alias self-signed
+ * certificate.
* @return the input collection, ordered with own certificate first, and CA's
* self-signed certificate last.
*/
private LinkedList orderChain(Collection chain)
{
log.entering(this.getClass().getName(), "orderChain"); //$NON-NLS-1$
-
+ LinkedList in = new LinkedList(chain);
+ int initialCount = in.size();
LinkedList result = new LinkedList();
-
-
+ Principal issuer = selfSignedCertificate.getIssuerDN();
+ ListIterator it;
+ outer: while (in.size() > 0)
+ {
+ for (it = in.listIterator(); it.hasNext();)
+ {
+ X509Certificate certificate = (X509Certificate) it.next();
+ if (issuer.equals(certificate.getSubjectDN()))
+ {
+ it.remove();
+ result.addLast(certificate);
+ issuer = certificate.getIssuerDN();
+ continue outer;
+ }
+ }
+ throw new IllegalArgumentException(
+ Messages.getFormattedString(Messages.getString("ImportCmd.7"), //$NON-NLS-1$
+ new Object[] { Integer.valueOf(result.size()),
+ Integer.valueOf(initialCount) }));
+ }
log.entering(this.getClass().getName(), "orderChain", result); //$NON-NLS-1$
return result;
}
@@ -646,13 +787,19 @@ class ImportCmd extends Command
CertificateEncodingException
{
log.entering(this.getClass().getName(), "findTrustAndUpdate"); //$NON-NLS-1$
-
- X509CertPath certPath = new X509CertPath(reply);
CertPathValidator validator = CertPathValidator.getInstance("PKIX"); //$NON-NLS-1$
+ X509CertPath certPath = new X509CertPath(reply);
PKIXCertPathValidatorResult cpvr = findTrustInStore(certPath, validator);
- if (cpvr == null && trustCACerts)
- cpvr = findTrustInCACerts(certPath, validator);
-
+ if (cpvr == null && trustCACerts) // try cacerts.gkr - a GKR key store
+ {
+ PKIXParameters params = getCertPathParameters(GKR, gkrCaCertsPathName);
+ cpvr = validate(validator, certPath, params);
+ if (cpvr == null) // try cacerts - a JKS key store
+ {
+ params = getCertPathParameters(JKS, jksCaCertsPathName);
+ cpvr = validate(validator, certPath, params);
+ }
+ }
boolean result = false;
if (cpvr == null)
{
@@ -671,12 +818,12 @@ class ImportCmd extends Command
}
else
{
- log.fine("Found a chain-of-trust anchored by " + cpvr.getTrustAnchor()); //$NON-NLS-1$
- Certificate trustedCert = cpvr.getTrustAnchor().getTrustedCert();
+ TrustAnchor anchor = cpvr.getTrustAnchor();
+ log.fine("Found a chain-of-trust anchored by " + anchor); //$NON-NLS-1$
+ Certificate trustedCert = anchor.getTrustedCert();
reply.addLast(trustedCert);
result = true;
}
-
log.entering(this.getClass().getName(), "findTrustAndUpdate", //$NON-NLS-1$
Boolean.valueOf(result));
return result;
@@ -705,33 +852,32 @@ class ImportCmd extends Command
return result;
}
- private PKIXCertPathValidatorResult findTrustInCACerts(X509CertPath certPath,
- CertPathValidator validator)
+ /**
+ * Return an instance of {@link PKIXParameters} constructed using a key store
+ * of the designated type and located at the designated path.
+ *
+ * @param type the type of the key-store to load.
+ * @param pathName the local File System fully qualified path name to the key
+ * store.
+ * @return an instance of <code>CertPathParameters</code> to use for
+ * validating certificates and certificate replies.
+ */
+ private PKIXParameters getCertPathParameters(String type, String pathName)
{
- log.entering(this.getClass().getName(), "findTrustInCACerts"); //$NON-NLS-1$
-
+ log.entering(this.getClass().getName(), "getCertPathParameters", //$NON-NLS-1$
+ new Object[] { type, pathName });
FileInputStream stream = null;
- PKIXCertPathValidatorResult result = null;
+ PKIXParameters result = null;
try
{
- KeyStore cacerts = KeyStore.getInstance("jks"); //$NON-NLS-1$
- String cacertsPath = SystemProperties.getProperty("java.home");
- String fs = SystemProperties.getProperty("file.separator"); //$NON-NLS-1$
- cacertsPath = new StringBuilder(cacertsPath).append(fs)
- .append("lib").append(fs) //$NON-NLS-1$
- .append("security").append(fs) //$NON-NLS-1$
- .append("cacerts").toString(); //$NON-NLS-1$
- stream = new FileInputStream(cacertsPath);
+ KeyStore cacerts = KeyStore.getInstance(type);
+ stream = new FileInputStream(pathName);
cacerts.load(stream, "changeit".toCharArray()); //$NON-NLS-1$
- PKIXParameters params = new PKIXParameters(cacerts);
- result = (PKIXCertPathValidatorResult) validator.validate(certPath,
- params);
+ result = new PKIXParameters(cacerts);
}
catch (Exception x)
{
- log.log(Level.FINE,
- "Exception in findTrustInCACerts(). Ignore + Return NULL", //$NON-NLS-1$
- x);
+ log.log(Level.FINE, "Exception in getCertPathParameters(). Ignore", x); //$NON-NLS-1$
}
finally
{
@@ -744,8 +890,27 @@ class ImportCmd extends Command
{
}
}
+ log.exiting(this.getClass().getName(), "getCertPathParameters", result); //$NON-NLS-1$
+ return result;
+ }
- log.exiting(this.getClass().getName(), "findTrustInCACerts", result); //$NON-NLS-1$
+ private PKIXCertPathValidatorResult validate(CertPathValidator validator,
+ X509CertPath certPath,
+ PKIXParameters params)
+ {
+ log.entering(this.getClass().getName(), "validate"); //$NON-NLS-1$
+ PKIXCertPathValidatorResult result = null;
+ if (params != null)
+ try
+ {
+ result = (PKIXCertPathValidatorResult) validator.validate(certPath,
+ params);
+ }
+ catch (Exception x)
+ {
+ log.log(Level.FINE, "Exception in validate(). Ignore", x); //$NON-NLS-1$
+ }
+ log.exiting(this.getClass().getName(), "validate", result); //$NON-NLS-1$
return result;
}
}
diff --git a/tools/gnu/classpath/tools/keytool/KeyCloneCmd.java b/tools/gnu/classpath/tools/keytool/KeyCloneCmd.java
index 5936719f7..61a8eb880 100644
--- a/tools/gnu/classpath/tools/keytool/KeyCloneCmd.java
+++ b/tools/gnu/classpath/tools/keytool/KeyCloneCmd.java
@@ -38,6 +38,12 @@ exception statement from your version. */
package gnu.classpath.tools.keytool;
+import gnu.classpath.tools.getopt.ClasspathToolParser;
+import gnu.classpath.tools.getopt.Option;
+import gnu.classpath.tools.getopt.OptionException;
+import gnu.classpath.tools.getopt.OptionGroup;
+import gnu.classpath.tools.getopt.Parser;
+
import java.io.IOException;
import java.security.Key;
import java.security.KeyStoreException;
@@ -90,7 +96,7 @@ import javax.security.auth.callback.UnsupportedCallbackException;
* material of the newly cloned copy of the <i>Key Entry</i>.
* <p></dd>
*
- * <dt>-storetype STORE_TYP}</dt>
+ * <dt>-storetype STORE_TYPE</dt>
* <dd>Use this option to specify the type of the key store to use. The
* default value, if this option is omitted, is that of the property
* <code>keystore.type</code> in the security properties file, which is
@@ -132,14 +138,14 @@ import javax.security.auth.callback.UnsupportedCallbackException;
class KeyCloneCmd extends Command
{
private static final Logger log = Logger.getLogger(KeyCloneCmd.class.getName());
- private String _alias;
- private String _destAlias;
- private String _password;
- private String _newPassword;
- private String _ksType;
- private String _ksURL;
- private String _ksPassword;
- private String _providerClassName;
+ protected String _alias;
+ protected String _destAlias;
+ protected String _password;
+ protected String _newPassword;
+ protected String _ksType;
+ protected String _ksURL;
+ protected String _ksPassword;
+ protected String _providerClassName;
private String destinationAlias;
private char[] newKeyPasswordChars;
@@ -197,58 +203,18 @@ class KeyCloneCmd extends Command
// life-cycle methods -------------------------------------------------------
- int processArgs(String[] args, int i)
- {
- int limit = args.length;
- String opt;
- while (++i < limit)
- {
- opt = args[i];
- log.finest("args[" + i + "]=" + opt); //$NON-NLS-1$ //$NON-NLS-2$
- if (opt == null || opt.length() == 0)
- continue;
-
- if ("-alias".equals(opt)) // -alias ALIAS //$NON-NLS-1$
- _alias = args[++i];
- else if ("-dest".equals(opt)) // -dest ALIAS //$NON-NLS-1$
- _destAlias = args[++i];
- else if ("-keypass".equals(opt)) // -keypass PASSWORD //$NON-NLS-1$
- _password = args[++i];
- else if ("-new".equals(opt)) // -new PASSWORD //$NON-NLS-1$
- _newPassword = args[++i];
- else if ("-storetype".equals(opt)) // -storetype STORE_TYPE //$NON-NLS-1$
- _ksType = args[++i];
- else if ("-keystore".equals(opt)) // -keystore URL //$NON-NLS-1$
- _ksURL = args[++i];
- else if ("-storepass".equals(opt)) // -storepass PASSWORD //$NON-NLS-1$
- _ksPassword = args[++i];
- else if ("-provider".equals(opt)) // -provider PROVIDER_CLASS_NAME //$NON-NLS-1$
- _providerClassName = args[++i];
- else if ("-v".equals(opt)) //$NON-NLS-1$
- verbose = true;
- else
- break;
- }
-
- return i;
- }
-
void setup() throws Exception
{
setKeyStoreParams(_providerClassName, _ksType, _ksPassword, _ksURL);
setAliasParam(_alias);
setKeyPasswordNoPrompt(_password);
setDestinationAlias(_destAlias);
-// setNewKeyPassword(_newPassword);
log.finer("-keyclone handler will use the following options:"); //$NON-NLS-1$
log.finer(" -alias=" + alias); //$NON-NLS-1$
log.finer(" -dest=" + destinationAlias); //$NON-NLS-1$
- log.finer(" -keypass=" + _password); //$NON-NLS-1$
- log.finer(" -new=" + _newPassword); //$NON-NLS-1$
log.finer(" -storetype=" + storeType); //$NON-NLS-1$
log.finer(" -keystore=" + storeURL); //$NON-NLS-1$
- log.finer(" -storepass=" + String.valueOf(storePasswordChars)); //$NON-NLS-1$
log.finer(" -provider=" + provider); //$NON-NLS-1$
log.finer(" -v=" + verbose); //$NON-NLS-1$
}
@@ -276,6 +242,100 @@ class KeyCloneCmd extends Command
// own methods --------------------------------------------------------------
+ Parser getParser()
+ {
+ log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$
+
+ Parser result = new ClasspathToolParser(Main.KEYCLONE_CMD, true);
+ result.setHeader(Messages.getString("KeyCloneCmd.22")); //$NON-NLS-1$
+ result.setFooter(Messages.getString("KeyCloneCmd.21")); //$NON-NLS-1$
+ OptionGroup options = new OptionGroup(Messages.getString("KeyCloneCmd.20")); //$NON-NLS-1$
+ options.add(new Option(Main.ALIAS_OPT,
+ Messages.getString("KeyCloneCmd.19"), //$NON-NLS-1$
+ Messages.getString("KeyCloneCmd.16")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _alias = argument;
+ }
+ });
+ options.add(new Option(Main.DEST_OPT,
+ Messages.getString("KeyCloneCmd.17"), //$NON-NLS-1$
+ Messages.getString("KeyCloneCmd.16")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _destAlias = argument;
+ }
+ });
+ options.add(new Option(Main.KEYPASS_OPT,
+ Messages.getString("KeyCloneCmd.15"), //$NON-NLS-1$
+ Messages.getString("KeyCloneCmd.6")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _password = argument;
+ }
+ });
+ options.add(new Option(Main.NEW_OPT,
+ Messages.getString("KeyCloneCmd.13"), //$NON-NLS-1$
+ Messages.getString("KeyCloneCmd.6")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _newPassword = argument;
+ }
+ });
+ options.add(new Option(Main.STORETYPE_OPT,
+ Messages.getString("KeyCloneCmd.11"), //$NON-NLS-1$
+ Messages.getString("KeyCloneCmd.10")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksType = argument;
+ }
+ });
+ options.add(new Option(Main.KEYSTORE_OPT,
+ Messages.getString("KeyCloneCmd.9"), //$NON-NLS-1$
+ Messages.getString("KeyCloneCmd.8")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksURL = argument;
+ }
+ });
+ options.add(new Option(Main.STOREPASS_OPT,
+ Messages.getString("KeyCloneCmd.7"), //$NON-NLS-1$
+ Messages.getString("KeyCloneCmd.6")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksPassword = argument;
+ }
+ });
+ options.add(new Option(Main.PROVIDER_OPT,
+ Messages.getString("KeyCloneCmd.5"), //$NON-NLS-1$
+ Messages.getString("KeyCloneCmd.4")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _providerClassName = argument;
+ }
+ });
+ options.add(new Option(Main.VERBOSE_OPT,
+ Messages.getString("KeyCloneCmd.3")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ verbose = true;
+ }
+ });
+ result.add(options);
+
+ log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$
+ return result;
+ }
+
private void setDestinationAlias(String name) throws IOException,
UnsupportedCallbackException
{
@@ -294,9 +354,9 @@ class KeyCloneCmd extends Command
private void setNewKeyPassword(String password) throws IOException,
UnsupportedCallbackException
{
- if (password != null) // ask user to provide one
+ if (password != null)
newKeyPasswordChars = password.toCharArray();
- else
+ else // ask user to provide one
{
boolean ok = false;
Callback[] prompts = new Callback[1];
diff --git a/tools/gnu/classpath/tools/keytool/KeyPasswdCmd.java b/tools/gnu/classpath/tools/keytool/KeyPasswdCmd.java
index 9dc7b8164..83beb161b 100644
--- a/tools/gnu/classpath/tools/keytool/KeyPasswdCmd.java
+++ b/tools/gnu/classpath/tools/keytool/KeyPasswdCmd.java
@@ -39,6 +39,11 @@ exception statement from your version. */
package gnu.classpath.tools.keytool;
import gnu.classpath.SystemProperties;
+import gnu.classpath.tools.getopt.ClasspathToolParser;
+import gnu.classpath.tools.getopt.Option;
+import gnu.classpath.tools.getopt.OptionException;
+import gnu.classpath.tools.getopt.OptionGroup;
+import gnu.classpath.tools.getopt.Parser;
import java.io.IOException;
import java.security.Key;
@@ -86,7 +91,7 @@ import javax.security.auth.callback.UnsupportedCallbackException;
* private key material of the designated Key Entry.
* <p></dd>
*
- * <dt>-storetype STORE_TYP}</dt>
+ * <dt>-storetype STORE_TYPE</dt>
* <dd>Use this option to specify the type of the key store to use. The
* default value, if this option is omitted, is that of the property
* <code>keystore.type</code> in the security properties file, which is
@@ -128,13 +133,13 @@ import javax.security.auth.callback.UnsupportedCallbackException;
class KeyPasswdCmd extends Command
{
private static final Logger log = Logger.getLogger(KeyPasswdCmd.class.getName());
- private String _alias;
- private String _password;
- private String _newPassword;
- private String _ksType;
- private String _ksURL;
- private String _ksPassword;
- private String _providerClassName;
+ protected String _alias;
+ protected String _password;
+ protected String _newPassword;
+ protected String _ksType;
+ protected String _ksURL;
+ protected String _ksPassword;
+ protected String _providerClassName;
private char[] newPasswordChars;
// default 0-arguments constructor
@@ -185,54 +190,17 @@ class KeyPasswdCmd extends Command
// life-cycle methods -------------------------------------------------------
- int processArgs(String[] args, int i)
- {
- int limit = args.length;
- String opt;
- while (++i < limit)
- {
- opt = args[i];
- log.finest("args[" + i + "]=" + opt); //$NON-NLS-1$ //$NON-NLS-2$
- if (opt == null || opt.length() == 0)
- continue;
-
- if ("-alias".equals(opt)) // -alias ALIAS //$NON-NLS-1$
- _alias = args[++i];
- else if ("-keypass".equals(opt)) // -keypass PASSWORD //$NON-NLS-1$
- _password = args[++i];
- else if ("-new".equals(opt)) // -new PASSWORD //$NON-NLS-1$
- _newPassword = args[++i];
- else if ("-storetype".equals(opt)) // -storetype STORE_TYPE //$NON-NLS-1$
- _ksType = args[++i];
- else if ("-keystore".equals(opt)) // -keystore URL //$NON-NLS-1$
- _ksURL = args[++i];
- else if ("-storepass".equals(opt)) // -storepass PASSWORD //$NON-NLS-1$
- _ksPassword = args[++i];
- else if ("-provider".equals(opt)) // -provider PROVIDER_CLASS_NAME //$NON-NLS-1$
- _providerClassName = args[++i];
- else if ("-v".equals(opt)) //$NON-NLS-1$
- verbose = true;
- else
- break;
- }
-
- return i;
- }
-
void setup() throws Exception
{
setKeyStoreParams(_providerClassName, _ksType, _ksPassword, _ksURL);
setAliasParam(_alias);
setKeyPasswordNoPrompt(_password);
-// setNewKeyPassword(_newPassword);
log.finer("-keypasswd handler will use the following options:"); //$NON-NLS-1$
log.finer(" -alias=" + alias); //$NON-NLS-1$
- log.finer(" -keypass=" + _password); //$NON-NLS-1$
log.finer(" -new=" + _newPassword); //$NON-NLS-1$
log.finer(" -storetype=" + storeType); //$NON-NLS-1$
log.finer(" -keystore=" + storeURL); //$NON-NLS-1$
- log.finer(" -storepass=" + String.valueOf(storePasswordChars)); //$NON-NLS-1$
log.finer(" -provider=" + provider); //$NON-NLS-1$
log.finer(" -v=" + verbose); //$NON-NLS-1$
}
@@ -259,6 +227,91 @@ class KeyPasswdCmd extends Command
// own methods --------------------------------------------------------------
+ Parser getParser()
+ {
+ log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$
+
+ Parser result = new ClasspathToolParser(Main.KEYPASSWD_CMD, true);
+ result.setHeader(Messages.getString("KeyPasswdCmd.23")); //$NON-NLS-1$
+ result.setFooter(Messages.getString("KeyPasswdCmd.22")); //$NON-NLS-1$
+ OptionGroup options = new OptionGroup(Messages.getString("KeyPasswdCmd.21")); //$NON-NLS-1$
+ options.add(new Option(Main.ALIAS_OPT,
+ Messages.getString("KeyPasswdCmd.20"), //$NON-NLS-1$
+ Messages.getString("KeyPasswdCmd.19")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _alias = argument;
+ }
+ });
+ options.add(new Option(Main.KEYPASS_OPT,
+ Messages.getString("KeyPasswdCmd.18"), //$NON-NLS-1$
+ Messages.getString("KeyPasswdCmd.9")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _password = argument;
+ }
+ });
+ options.add(new Option(Main.NEW_OPT,
+ Messages.getString("KeyPasswdCmd.16"), //$NON-NLS-1$
+ Messages.getString("KeyPasswdCmd.9")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _newPassword = argument;
+ }
+ });
+ options.add(new Option(Main.STORETYPE_OPT,
+ Messages.getString("KeyPasswdCmd.14"), //$NON-NLS-1$
+ Messages.getString("KeyPasswdCmd.13")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksType = argument;
+ }
+ });
+ options.add(new Option(Main.KEYSTORE_OPT,
+ Messages.getString("KeyPasswdCmd.12"), //$NON-NLS-1$
+ Messages.getString("KeyPasswdCmd.11")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksURL = argument;
+ }
+ });
+ options.add(new Option(Main.STOREPASS_OPT,
+ Messages.getString("KeyPasswdCmd.10"), //$NON-NLS-1$
+ Messages.getString("KeyPasswdCmd.9")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksPassword = argument;
+ }
+ });
+ options.add(new Option(Main.PROVIDER_OPT,
+ Messages.getString("KeyPasswdCmd.8"), //$NON-NLS-1$
+ Messages.getString("KeyPasswdCmd.7")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _providerClassName = argument;
+ }
+ });
+ options.add(new Option(Main.VERBOSE_OPT,
+ Messages.getString("KeyPasswdCmd.6")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ verbose = true;
+ }
+ });
+ result.add(options);
+
+ log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$
+ return result;
+ }
+
/**
* Set the new password to use for protecting Alias's private key.
*
diff --git a/tools/gnu/classpath/tools/keytool/ListCmd.java b/tools/gnu/classpath/tools/keytool/ListCmd.java
index 655242785..99fcfa2cf 100644
--- a/tools/gnu/classpath/tools/keytool/ListCmd.java
+++ b/tools/gnu/classpath/tools/keytool/ListCmd.java
@@ -38,6 +38,11 @@ exception statement from your version. */
package gnu.classpath.tools.keytool;
+import gnu.classpath.tools.getopt.ClasspathToolParser;
+import gnu.classpath.tools.getopt.Option;
+import gnu.classpath.tools.getopt.OptionException;
+import gnu.classpath.tools.getopt.OptionGroup;
+import gnu.classpath.tools.getopt.Parser;
import gnu.java.security.util.Base64;
import java.io.IOException;
@@ -64,7 +69,7 @@ import java.util.logging.Logger;
* omitted from the command line.
* <p></dd>
*
- * <dt>-storetype STORE_TYP}</dt>
+ * <dt>-storetype STORE_TYPE</dt>
* <dd>Use this option to specify the type of the key store to use. The
* default value, if this option is omitted, is that of the property
* <code>keystore.type</code> in the security properties file, which is
@@ -113,12 +118,12 @@ import java.util.logging.Logger;
class ListCmd extends Command
{
private static final Logger log = Logger.getLogger(ListCmd.class.getName());
- private String _alias;
- private String _ksType;
- private String _ksURL;
- private String _ksPassword;
- private String _providerClassName;
- private boolean rfc;
+ protected String _alias;
+ protected String _ksType;
+ protected String _ksURL;
+ protected String _ksPassword;
+ protected String _providerClassName;
+ protected boolean rfc;
private boolean all;
// default 0-arguments constructor
@@ -166,44 +171,11 @@ class ListCmd extends Command
// life-cycle methods -------------------------------------------------------
- int processArgs(String[] args, int i)
- {
- int limit = args.length;
- String opt;
- while (++i < limit)
- {
- opt = args[i];
- log.finest("args[" + i + "]=" + opt); //$NON-NLS-1$ //$NON-NLS-2$
- if (opt == null || opt.length() == 0)
- continue;
-
- if ("-alias".equals(opt)) // -alias ALIAS //$NON-NLS-1$
- _alias = args[++i];
- else if ("-storetype".equals(opt)) // -storetype STORE_TYPE //$NON-NLS-1$
- _ksType = args[++i];
- else if ("-keystore".equals(opt)) // -keystore URL //$NON-NLS-1$
- _ksURL = args[++i];
- else if ("-storepass".equals(opt)) // -storepass PASSWORD //$NON-NLS-1$
- _ksPassword = args[++i];
- else if ("-provider".equals(opt)) // -provider PROVIDER_CLASS_NAME //$NON-NLS-1$
- _providerClassName = args[++i];
- else if ("-v".equals(opt)) //$NON-NLS-1$
- verbose = true;
- else if ("-rfc".equals(opt)) //$NON-NLS-1$
- rfc = true;
- else
- break;
- }
-
- all = _alias == null;
-
- return i;
- }
-
void setup() throws Exception
{
setOutputStreamParam(null); // use stdout
setKeyStoreParams(_providerClassName, _ksType, _ksPassword, _ksURL);
+ all = _alias == null;
if (! all)
setAliasParam(_alias);
@@ -218,7 +190,6 @@ class ListCmd extends Command
log.finer(" -alias=" + alias); //$NON-NLS-1$
log.finer(" -storetype=" + storeType); //$NON-NLS-1$
log.finer(" -keystore=" + storeURL); //$NON-NLS-1$
- log.finer(" -storepass=" + String.valueOf(storePasswordChars)); //$NON-NLS-1$
log.finer(" -provider=" + provider); //$NON-NLS-1$
log.finer(" -v=" + verbose); //$NON-NLS-1$
log.finer(" -rfc=" + rfc); //$NON-NLS-1$
@@ -254,6 +225,81 @@ class ListCmd extends Command
// own methods --------------------------------------------------------------
+ Parser getParser()
+ {
+ log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$
+
+ Parser result = new ClasspathToolParser(Main.LIST_CMD, true);
+ result.setHeader(Messages.getString("ListCmd.20")); //$NON-NLS-1$
+ result.setFooter(Messages.getString("ListCmd.19")); //$NON-NLS-1$
+ OptionGroup options = new OptionGroup(Messages.getString("ListCmd.18")); //$NON-NLS-1$
+ options.add(new Option(Main.ALIAS_OPT,
+ Messages.getString("ListCmd.17"), //$NON-NLS-1$
+ Messages.getString("ListCmd.16")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _alias = argument;
+ }
+ });
+ options.add(new Option(Main.STORETYPE_OPT,
+ Messages.getString("ListCmd.15"), //$NON-NLS-1$
+ Messages.getString("ListCmd.14")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksType = argument;
+ }
+ });
+ options.add(new Option(Main.KEYSTORE_OPT,
+ Messages.getString("ListCmd.13"), //$NON-NLS-1$
+ Messages.getString("ListCmd.12")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksURL = argument;
+ }
+ });
+ options.add(new Option(Main.STOREPASS_OPT,
+ Messages.getString("ListCmd.11"), //$NON-NLS-1$
+ Messages.getString("ListCmd.10")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksPassword = argument;
+ }
+ });
+ options.add(new Option(Main.PROVIDER_OPT,
+ Messages.getString("ListCmd.9"), //$NON-NLS-1$
+ Messages.getString("ListCmd.8")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _providerClassName = argument;
+ }
+ });
+ options.add(new Option(Main.VERBOSE_OPT,
+ Messages.getString("ListCmd.7")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ verbose = true;
+ }
+ });
+ options.add(new Option(Main.RFC_OPT,
+ Messages.getString("ListCmd.6")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ rfc = true;
+ }
+ });
+ result.add(options);
+
+ log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$
+ return result;
+ }
+
/**
* Prints the certificate(s) associated with the designated alias.
*
@@ -312,7 +358,7 @@ class ListCmd extends Command
private void print1Chain(Certificate[] chain, PrintWriter writer)
throws CertificateEncodingException
{
- if (!verbose && !rfc)
+ if (! verbose && ! rfc)
fingerprint(chain[0], writer);
else
{
diff --git a/tools/gnu/classpath/tools/keytool/Main.java b/tools/gnu/classpath/tools/keytool/Main.java
index fb7aa4509..582aba082 100644
--- a/tools/gnu/classpath/tools/keytool/Main.java
+++ b/tools/gnu/classpath/tools/keytool/Main.java
@@ -38,8 +38,12 @@ exception statement from your version. */
package gnu.classpath.tools.keytool;
-import gnu.classpath.tools.HelpPrinter;
import gnu.classpath.tools.common.ProviderUtil;
+import gnu.classpath.tools.getopt.ClasspathToolParser;
+import gnu.classpath.tools.getopt.Option;
+import gnu.classpath.tools.getopt.OptionException;
+import gnu.classpath.tools.getopt.OptionGroup;
+import gnu.classpath.tools.getopt.Parser;
import gnu.java.security.Registry;
import gnu.javax.crypto.jce.GnuCrypto;
import gnu.javax.security.auth.callback.GnuCallbacks;
@@ -57,8 +61,51 @@ import java.util.logging.Logger;
public class Main
{
private static final Logger log = Logger.getLogger(Main.class.getName());
- /** The relative file path to the command tool's help text. */
- private static final String HELP_PATH = "keytool/keytool.txt"; //$NON-NLS-1$
+ static final String KEYTOOL_TOOL = "keytool"; //$NON-NLS-1$
+ static final String GENKEY_CMD = "genkey"; //$NON-NLS-1$
+ static final String IMPORT_CMD = "import"; //$NON-NLS-1$
+ static final String SELFCERT_CMD = "selfcert"; //$NON-NLS-1$
+ static final String IDENTITYDB_CMD = "identitydb"; //$NON-NLS-1$
+ static final String CERTREQ_CMD = "certreq"; //$NON-NLS-1$
+ static final String EXPORT_CMD = "export"; //$NON-NLS-1$
+ static final String LIST_CMD = "list"; //$NON-NLS-1$
+ static final String PRINTCERT_CMD = "printcert"; //$NON-NLS-1$
+ static final String KEYCLONE_CMD = "keyclone"; //$NON-NLS-1$
+ static final String STOREPASSWD_CMD = "storepasswd"; //$NON-NLS-1$
+ static final String KEYPASSWD_CMD = "keypasswd"; //$NON-NLS-1$
+ static final String DELETE_CMD = "delete"; //$NON-NLS-1$
+
+ static final String _GENKEY = "-" + GENKEY_CMD; //$NON-NLS-1$
+ static final String _IMPORT = "-" + IMPORT_CMD; //$NON-NLS-1$
+ static final String _SELFCERT = "-" + SELFCERT_CMD; //$NON-NLS-1$
+ static final String _IDENTITYDB = "-" + IDENTITYDB_CMD; //$NON-NLS-1$
+ static final String _CERTREQ = "-" + CERTREQ_CMD; //$NON-NLS-1$
+ static final String _EXPORT = "-" + EXPORT_CMD; //$NON-NLS-1$
+ static final String _LIST = "-" + LIST_CMD; //$NON-NLS-1$
+ static final String _PRINTCERT = "-" + PRINTCERT_CMD; //$NON-NLS-1$
+ static final String _KEYCLONE = "-" + KEYCLONE_CMD; //$NON-NLS-1$
+ static final String _STOREPASSWD = "-" + STOREPASSWD_CMD; //$NON-NLS-1$
+ static final String _KEYPASSWD = "-" + KEYPASSWD_CMD; //$NON-NLS-1$
+ static final String _DELETE = "-" + DELETE_CMD; //$NON-NLS-1$
+ static final String _HELP = "-help"; //$NON-NLS-1$
+
+ static final String ALIAS_OPT = "alias"; //$NON-NLS-1$
+ static final String SIGALG_OPT = "sigalg"; //$NON-NLS-1$
+ static final String KEYALG_OPT = "keyalg"; //$NON-NLS-1$
+ static final String KEYSIZE_OPT = "keysize"; //$NON-NLS-1$
+ static final String KEYPASS_OPT = "keypass"; //$NON-NLS-1$
+ static final String VALIDITY_OPT = "validity"; //$NON-NLS-1$
+ static final String STORETYPE_OPT = "storetype"; //$NON-NLS-1$
+ static final String STOREPASS_OPT = "storepass"; //$NON-NLS-1$
+ static final String KEYSTORE_OPT = "keystore"; //$NON-NLS-1$
+ static final String PROVIDER_OPT = "provider"; //$NON-NLS-1$
+ static final String FILE_OPT = "file"; //$NON-NLS-1$
+ static final String VERBOSE_OPT = "v"; //$NON-NLS-1$
+ static final String DEST_OPT = "dest"; //$NON-NLS-1$
+ static final String NEW_OPT = "new"; //$NON-NLS-1$
+ static final String RFC_OPT = "rfc"; //$NON-NLS-1$
+ static final String DNAME_OPT = "dname"; //$NON-NLS-1$
+
/** The Preferences key name for the last issued certificate serial nbr. */
static final String LAST_SERIAL_NUMBER = "lastSerialNumber"; //$NON-NLS-1$
/** Constant denoting the X.509 certificate type. */
@@ -70,6 +117,8 @@ public class Main
private int gnuCryptoProviderNdx = -2;
/** The new position of GNU Callbacks provider if it is not already installed. */
private int gnuCallbacksNdx = -2;
+ /** The command line parser. */
+ private Parser cmdLineParser;
private Main()
{
@@ -81,117 +130,140 @@ public class Main
log.entering(Main.class.getName(), "main", args); //$NON-NLS-1$
Main tool = new Main();
+ int result = 1;
try
{
tool.setup();
tool.start(args);
+ result = 0;
+ }
+ catch (OptionException x)
+ {
+ System.err.println(x.getMessage());
+ if (tool.cmdLineParser != null)
+ tool.cmdLineParser.printHelp();
}
catch (SecurityException x)
{
log.throwing(Main.class.getName(), "main", x); //$NON-NLS-1$
- System.err.println(Messages.getString("Main.6") + x.getMessage()); //$NON-NLS-1$
+ System.err.println(Messages.getFormattedString("Main.6", //$NON-NLS-1$
+ x.getMessage()));
}
catch (Exception x)
{
log.throwing(Main.class.getName(), "main", x); //$NON-NLS-1$
- System.err.println(Messages.getString("Main.8") + x); //$NON-NLS-1$
+ System.err.println(Messages.getFormattedString("Main.8", x)); //$NON-NLS-1$
}
finally
- {
- tool.teardown();
- }
+ {
+ tool.teardown();
+ }
- log.exiting(Main.class.getName(), "main"); //$NON-NLS-1$
- // System.exit(0);
+ log.exiting(Main.class.getName(), "main", Integer.valueOf(result)); //$NON-NLS-1$
+ System.exit(result);
}
// helper methods -----------------------------------------------------------
+ private void setup()
+ {
+ log.entering(this.getClass().getName(), "setup"); //$NON-NLS-1$
+
+ cmdLineParser = getParser();
+ gnuCryptoProviderNdx = ProviderUtil.addProvider(new GnuCrypto());
+ gnuCallbacksNdx = ProviderUtil.addProvider(new GnuCallbacks());
+
+ log.exiting(this.getClass().getName(), "setup"); //$NON-NLS-1$
+ }
+
private void start(String[] args) throws Exception
{
- log.entering(this.getClass().getName(), "start", args); //$NON-NLS-1$
+ log.entering(this.getClass().getName(), "start"); //$NON-NLS-1$
- if (args == null)
- args = new String[0];
+ if (args == null || args.length == 0)
+ throw new OptionException(""); //$NON-NLS-1$
- int limit = args.length;
- log.finest("args.length=" + limit); //$NON-NLS-1$
- int i = 0;
String opt;
Command cmd;
- while (i < limit)
+ while (args.length > 0)
{
- opt = args[i];
- log.finest("args[" + i + "]=" + opt); //$NON-NLS-1$ //$NON-NLS-2$
- if (opt == null || opt.length() == 0)
- continue;
-
+ opt = args[0];
cmd = null;
- if ("-genkey".equals(opt)) //$NON-NLS-1$
+ if (_GENKEY.equals(opt))
cmd = new GenKeyCmd();
- else if ("-import".equals(opt)) //$NON-NLS-1$
+ else if (_IMPORT.equals(opt))
cmd = new ImportCmd();
- else if ("-selfcert".equals(opt)) //$NON-NLS-1$
+ else if (_SELFCERT.equals(opt))
cmd = new SelfCertCmd();
- else if ("-identitydb".equals(opt)) //$NON-NLS-1$
+ else if (_IDENTITYDB.equals(opt))
cmd = new IdentityDBCmd();
- else if ("-certreq".equals(opt)) //$NON-NLS-1$
+ else if (_CERTREQ.equals(opt))
cmd = new CertReqCmd();
- else if ("-export".equals(opt)) //$NON-NLS-1$
+ else if (_EXPORT.equals(opt))
cmd = new ExportCmd();
- else if ("-list".equals(opt)) //$NON-NLS-1$
+ else if (_LIST.equals(opt))
cmd = new ListCmd();
- else if ("-printcert".equals(opt)) //$NON-NLS-1$
+ else if (_PRINTCERT.equals(opt))
cmd = new PrintCertCmd();
- else if ("-keyclone".equals(opt)) //$NON-NLS-1$
+ else if (_KEYCLONE.equals(opt))
cmd = new KeyCloneCmd();
- else if ("-storepasswd".equals(opt)) //$NON-NLS-1$
+ else if (_STOREPASSWD.equals(opt))
cmd = new StorePasswdCmd();
- else if ("-keypasswd".equals(opt)) //$NON-NLS-1$
+ else if (_KEYPASSWD.equals(opt))
cmd = new KeyPasswdCmd();
- else if ("-delete".equals(opt)) //$NON-NLS-1$
+ else if (_DELETE.equals(opt))
cmd = new DeleteCmd();
- else if ("-help".equals(opt)) //$NON-NLS-1$
- {
- printHelp();
- i++;
- }
+ else if (_HELP.equals(opt))
+ throw new OptionException(""); //$NON-NLS-1$
else
- {
- log.fine("Unknown command [" + opt + "] at index #" + i //$NON-NLS-1$ //$NON-NLS-2$
- + ". Arguments from that token onward will be ignored"); //$NON-NLS-1$
- break;
- }
-
- if (cmd != null)
- {
- i = cmd.processArgs(args, i);
- cmd.doCommand();
- }
- }
-
- // the -help command is the default; i.e.
- // keytool
- // is equivalent to:
- // keytool -help
- if (i == 0)
- printHelp();
+ throw new OptionException(Messages.getFormattedString("Main.18", //$NON-NLS-1$
+ opt));
- if (i < limit) // more options than needed
- log.fine("Last recognized argument is assumed at index #" + (i - 1) //$NON-NLS-1$
- + ". Remaining arguments (" + args[i] + "...) will be ignored"); //$NON-NLS-1$ //$NON-NLS-2$
+ String[] cmdArgs = new String[args.length - 1];
+ System.arraycopy(args, 1, cmdArgs, 0, cmdArgs.length);
+ args = cmd.processArgs(cmdArgs);
+ cmd.doCommand();
+ }
log.exiting(this.getClass().getName(), "start"); //$NON-NLS-1$
}
- private void setup()
+ private Parser getParser()
{
- log.entering(this.getClass().getName(), "setup"); //$NON-NLS-1$
-
- gnuCryptoProviderNdx = ProviderUtil.addProvider(new GnuCrypto());
- gnuCallbacksNdx = ProviderUtil.addProvider(new GnuCallbacks());
-
- log.exiting(this.getClass().getName(), "setup"); //$NON-NLS-1$
+ log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$
+
+ Parser result = new ClasspathToolParser(KEYTOOL_TOOL, true);
+ result.setHeader(Messages.getString("Main.19")); //$NON-NLS-1$
+ result.setFooter(Messages.getString("Main.20")); //$NON-NLS-1$
+ OptionGroup cmdGroup = new OptionGroup(Messages.getString("Main.21")); //$NON-NLS-1$
+ cmdGroup.add(new NoParseOption(GENKEY_CMD,
+ Messages.getString("Main.22"))); //$NON-NLS-1$
+ cmdGroup.add(new NoParseOption(IMPORT_CMD,
+ Messages.getString("Main.23"))); //$NON-NLS-1$
+ cmdGroup.add(new NoParseOption(SELFCERT_CMD,
+ Messages.getString("Main.24"))); //$NON-NLS-1$
+ cmdGroup.add(new NoParseOption(IDENTITYDB_CMD,
+ Messages.getString("Main.25"))); //$NON-NLS-1$
+ cmdGroup.add(new NoParseOption(CERTREQ_CMD,
+ Messages.getString("Main.26"))); //$NON-NLS-1$
+ cmdGroup.add(new NoParseOption(EXPORT_CMD,
+ Messages.getString("Main.27"))); //$NON-NLS-1$
+ cmdGroup.add(new NoParseOption(LIST_CMD,
+ Messages.getString("Main.28"))); //$NON-NLS-1$
+ cmdGroup.add(new NoParseOption(PRINTCERT_CMD,
+ Messages.getString("Main.29"))); //$NON-NLS-1$
+ cmdGroup.add(new NoParseOption(KEYCLONE_CMD,
+ Messages.getString("Main.30"))); //$NON-NLS-1$
+ cmdGroup.add(new NoParseOption(STOREPASSWD_CMD,
+ Messages.getString("Main.31"))); //$NON-NLS-1$
+ cmdGroup.add(new NoParseOption(KEYPASSWD_CMD,
+ Messages.getString("Main.32"))); //$NON-NLS-1$
+ cmdGroup.add(new NoParseOption(DELETE_CMD,
+ Messages.getString("Main.33"))); //$NON-NLS-1$
+ result.add(cmdGroup);
+
+ log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$
+ return result;
}
private void teardown()
@@ -213,7 +285,28 @@ public class Main
if (helpPrinted)
return;
- HelpPrinter.printHelp(HELP_PATH);
helpPrinted = true;
}
+
+ // Inner class(es)
+ // ==========================================================================
+
+ private class NoParseOption
+ extends Option
+ {
+ public NoParseOption(String name, String description)
+ {
+ super(name, description);
+ }
+
+ public NoParseOption(String name, String description, String param)
+ {
+ super(name, description, param);
+ }
+
+ public void parsed(String argument) throws OptionException
+ {
+ // do nothing
+ }
+ }
}
diff --git a/tools/gnu/classpath/tools/keytool/Messages.java b/tools/gnu/classpath/tools/keytool/Messages.java
index e3308e021..7ecaa1c37 100644
--- a/tools/gnu/classpath/tools/keytool/Messages.java
+++ b/tools/gnu/classpath/tools/keytool/Messages.java
@@ -54,7 +54,7 @@ import java.util.logging.Logger;
class Messages
{
private static final Logger log = Logger.getLogger(Messages.class.getName());
- private static final String BUNDLE_NAME = "gnu.classpath.tools.keytool.MessageBundle"; //$NON-NLS-1$
+ private static final String BUNDLE_NAME = "gnu.classpath.tools.keytool.messages";
private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME);
private static final Map CACHED_FORMATS = new HashMap(5);
@@ -88,7 +88,7 @@ class Messages
CACHED_FORMATS.put(key, mf);
}
- // if the argument is not an array, then build one consisiting of the
+ // if the argument is not an array, then build one consisting of the
// sole argument before passing it to the format() method
try
{
diff --git a/tools/gnu/classpath/tools/keytool/PrintCertCmd.java b/tools/gnu/classpath/tools/keytool/PrintCertCmd.java
index 9ba1d5970..d259258e7 100644
--- a/tools/gnu/classpath/tools/keytool/PrintCertCmd.java
+++ b/tools/gnu/classpath/tools/keytool/PrintCertCmd.java
@@ -38,6 +38,12 @@ exception statement from your version. */
package gnu.classpath.tools.keytool;
+import gnu.classpath.tools.getopt.ClasspathToolParser;
+import gnu.classpath.tools.getopt.Option;
+import gnu.classpath.tools.getopt.OptionException;
+import gnu.classpath.tools.getopt.OptionGroup;
+import gnu.classpath.tools.getopt.Parser;
+
import java.io.PrintWriter;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
@@ -63,7 +69,7 @@ import java.util.logging.Logger;
class PrintCertCmd extends Command
{
private static final Logger log = Logger.getLogger(PrintCertCmd.class.getName());
- private String _certFileName;
+ protected String _certFileName;
// default 0-arguments constructor
@@ -77,40 +83,18 @@ class PrintCertCmd extends Command
// life-cycle methods -------------------------------------------------------
- int processArgs(String[] args, int i)
- {
- int limit = args.length;
- String opt;
- while (++i < limit)
- {
- opt = args[i];
- log.finest("args[" + i + "]=" + opt);
- if (opt == null || opt.length() == 0)
- continue;
-
- if ("-file".equals(opt)) // -file FILE_NAME
- _certFileName = args[++i];
- else if ("-v".equals(opt))
- verbose = true;
- else
- break;
- }
-
- return i;
- }
-
void setup() throws Exception
{
setInputStreamParam(_certFileName);
- log.finer("-printcert handler will use the following options:");
- log.finer(" -file=" + _certFileName);
- log.finer(" -v=" + verbose);
+ log.finer("-printcert handler will use the following options:"); //$NON-NLS-1$
+ log.finer(" -file=" + _certFileName); //$NON-NLS-1$
+ log.finer(" -v=" + verbose); //$NON-NLS-1$
}
void start() throws CertificateException
{
- log.entering(getClass().getName(), "start");
+ log.entering(getClass().getName(), "start"); //$NON-NLS-1$
CertificateFactory x509Factory = CertificateFactory.getInstance(Main.X_509);
Certificate certificate = x509Factory.generateCertificate(inStream);
@@ -118,6 +102,39 @@ class PrintCertCmd extends Command
writer.println();
printVerbose(certificate, writer);
- log.exiting(getClass().getName(), "start");
+ log.exiting(getClass().getName(), "start"); //$NON-NLS-1$
+ }
+
+ // own methods --------------------------------------------------------------
+
+ Parser getParser()
+ {
+ log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$
+
+ Parser result = new ClasspathToolParser(Main.PRINTCERT_CMD, true);
+ result.setHeader(Messages.getString("PrintCertCmd.5")); //$NON-NLS-1$
+ result.setFooter(Messages.getString("PrintCertCmd.6")); //$NON-NLS-1$
+ OptionGroup options = new OptionGroup(Messages.getString("PrintCertCmd.7")); //$NON-NLS-1$
+ options.add(new Option(Main.FILE_OPT,
+ Messages.getString("PrintCertCmd.8"), //$NON-NLS-1$
+ Messages.getString("PrintCertCmd.9")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _certFileName = argument;
+ }
+ });
+ options.add(new Option(Main.VERBOSE_OPT,
+ Messages.getString("PrintCertCmd.10")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ verbose = true;
+ }
+ });
+ result.add(options);
+
+ log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$
+ return result;
}
}
diff --git a/tools/gnu/classpath/tools/keytool/SelfCertCmd.java b/tools/gnu/classpath/tools/keytool/SelfCertCmd.java
index db7d45994..db700a164 100644
--- a/tools/gnu/classpath/tools/keytool/SelfCertCmd.java
+++ b/tools/gnu/classpath/tools/keytool/SelfCertCmd.java
@@ -38,6 +38,11 @@ exception statement from your version. */
package gnu.classpath.tools.keytool;
+import gnu.classpath.tools.getopt.ClasspathToolParser;
+import gnu.classpath.tools.getopt.Option;
+import gnu.classpath.tools.getopt.OptionException;
+import gnu.classpath.tools.getopt.OptionGroup;
+import gnu.classpath.tools.getopt.Parser;
import gnu.java.security.x509.X500DistinguishedName;
import java.io.ByteArrayInputStream;
@@ -129,7 +134,7 @@ import javax.security.auth.x500.X500Principal;
*
* <dt>-keypass PASSWORD</dt>
*
- * <dt>-storetype STORE_TYP}</dt>
+ * <dt>-storetype STORE_TYPE</dt>
* <dd>Use this option to specify the type of the key store to use. The
* default value, if this option is omitted, is that of the property
* <code>keystore.type</code> in the security properties file, which is
@@ -171,15 +176,15 @@ import javax.security.auth.x500.X500Principal;
class SelfCertCmd extends Command
{
private static final Logger log = Logger.getLogger(SelfCertCmd.class.getName());
- private String _alias;
- private String _sigAlgorithm;
- private String _dName;
- private String _password;
- private String _validityStr;
- private String _ksType;
- private String _ksURL;
- private String _ksPassword;
- private String _providerClassName;
+ protected String _alias;
+ protected String _sigAlgorithm;
+ protected String _dName;
+ protected String _password;
+ protected String _validityStr;
+ protected String _ksType;
+ protected String _ksURL;
+ protected String _ksPassword;
+ protected String _providerClassName;
private X500DistinguishedName distinguishedName;
private int validityInDays;
@@ -253,71 +258,29 @@ class SelfCertCmd extends Command
// life-cycle methods -------------------------------------------------------
- int processArgs(String[] args, int i)
- {
- int limit = args.length;
- String opt;
- while (++i < limit)
- {
- opt = args[i];
- log.finest("args[" + i + "]=" + opt);
- if (opt == null || opt.length() == 0)
- continue;
-
- if ("-alias".equals(opt)) // -alias ALIAS
- _alias = args[++i];
- else if ("-sigalg".equals(opt)) // -sigalg ALGORITHM
- _sigAlgorithm = args[++i];
- else if ("-dname".equals(opt)) // -dname NAME
- _dName = args[++i];
- else if ("-keypass".equals(opt)) // -keypass PASSWORD
- _password = args[++i];
- else if ("-validity".equals(opt)) // -validity DAY_COUNT
- _validityStr = args[++i];
- else if ("-storetype".equals(opt)) // -storetype STORE_TYPE
- _ksType = args[++i];
- else if ("-keystore".equals(opt)) // -keystore URL
- _ksURL = args[++i];
- else if ("-storepass".equals(opt)) // -storepass PASSWORD
- _ksPassword = args[++i];
- else if ("-provider".equals(opt)) // -provider PROVIDER_CLASS_NAME
- _providerClassName = args[++i];
- else if ("-v".equals(opt))
- verbose = true;
- else
- break;
- }
-
- return i;
- }
-
void setup() throws Exception
{
setKeyStoreParams(_providerClassName, _ksType, _ksPassword, _ksURL);
setAliasParam(_alias);
setKeyPasswordNoPrompt(_password);
-// setDName(_dName);
setValidityParam(_validityStr);
-// setSignatureAlgorithm(_sigAlgorithm);
-
- log.finer("-selfcert handler will use the following options:");
- log.finer(" -alias=" + alias);
- log.finer(" -sigalg=" + _sigAlgorithm);
- log.finer(" -dname=" + _dName);
- log.finer(" -keypass=" + _password);
- log.finer(" -validity=" + validityInDays);
- log.finer(" -storetype=" + storeType);
- log.finer(" -keystore=" + storeURL);
- log.finer(" -storepass=" + String.valueOf(storePasswordChars));
- log.finer(" -provider=" + provider);
- log.finer(" -v=" + verbose);
+
+ log.finer("-selfcert handler will use the following options:"); //$NON-NLS-1$
+ log.finer(" -alias=" + alias); //$NON-NLS-1$
+ log.finer(" -sigalg=" + _sigAlgorithm); //$NON-NLS-1$
+ log.finer(" -dname=" + _dName); //$NON-NLS-1$
+ log.finer(" -validity=" + validityInDays); //$NON-NLS-1$
+ log.finer(" -storetype=" + storeType); //$NON-NLS-1$
+ log.finer(" -keystore=" + storeURL); //$NON-NLS-1$
+ log.finer(" -provider=" + provider); //$NON-NLS-1$
+ log.finer(" -v=" + verbose); //$NON-NLS-1$
}
void start() throws KeyStoreException, NoSuchAlgorithmException,
UnrecoverableKeyException, IOException, UnsupportedCallbackException,
InvalidKeyException, SignatureException, CertificateException
{
- log.entering(getClass().getName(), "start");
+ log.entering(getClass().getName(), "start"); //$NON-NLS-1$
// 1. get the key entry and certificate chain associated to alias
Key privateKey = getAliasPrivateKey();
@@ -337,7 +300,7 @@ class SelfCertCmd extends Command
byte[] derBytes = getSelfSignedCertificate(distinguishedName,
publicKey,
(PrivateKey) privateKey);
- CertificateFactory x509Factory = CertificateFactory.getInstance("X.509");
+ CertificateFactory x509Factory = CertificateFactory.getInstance("X.509"); //$NON-NLS-1$
ByteArrayInputStream bais = new ByteArrayInputStream(derBytes);
Certificate certificate = x509Factory.generateCertificate(bais);
@@ -348,11 +311,114 @@ class SelfCertCmd extends Command
// 7. persist the key store
saveKeyStore();
- log.exiting(getClass().getName(), "start");
+ log.exiting(getClass().getName(), "start"); //$NON-NLS-1$
}
// own methods --------------------------------------------------------------
+ Parser getParser()
+ {
+ log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$
+
+ Parser result = new ClasspathToolParser(Main.SELFCERT_CMD, true);
+ result.setHeader(Messages.getString("SelfCertCmd.14")); //$NON-NLS-1$
+ result.setFooter(Messages.getString("SelfCertCmd.15")); //$NON-NLS-1$
+ OptionGroup options = new OptionGroup(Messages.getString("SelfCertCmd.16")); //$NON-NLS-1$
+ options.add(new Option(Main.ALIAS_OPT,
+ Messages.getString("SelfCertCmd.17"), //$NON-NLS-1$
+ Messages.getString("SelfCertCmd.18")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _alias = argument;
+ }
+ });
+ options.add(new Option(Main.SIGALG_OPT,
+ Messages.getString("SelfCertCmd.19"), //$NON-NLS-1$
+ Messages.getString("SelfCertCmd.20")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _sigAlgorithm = argument;
+ }
+ });
+ options.add(new Option(Main.DNAME_OPT,
+ Messages.getString("SelfCertCmd.21"), //$NON-NLS-1$
+ Messages.getString("SelfCertCmd.22")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _dName = argument;
+ }
+ });
+ options.add(new Option(Main.KEYPASS_OPT,
+ Messages.getString("SelfCertCmd.23"), //$NON-NLS-1$
+ Messages.getString("SelfCertCmd.24")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _password = argument;
+ }
+ });
+ options.add(new Option(Main.VALIDITY_OPT,
+ Messages.getString("SelfCertCmd.25"), //$NON-NLS-1$
+ Messages.getString("SelfCertCmd.26")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _validityStr = argument;
+ }
+ });
+ options.add(new Option(Main.STORETYPE_OPT,
+ Messages.getString("SelfCertCmd.27"), //$NON-NLS-1$
+ Messages.getString("SelfCertCmd.28")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksType = argument;
+ }
+ });
+ options.add(new Option(Main.KEYSTORE_OPT,
+ Messages.getString("SelfCertCmd.29"), //$NON-NLS-1$
+ Messages.getString("SelfCertCmd.30")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksURL = argument;
+ }
+ });
+ options.add(new Option(Main.STOREPASS_OPT,
+ Messages.getString("SelfCertCmd.31"), //$NON-NLS-1$
+ Messages.getString("SelfCertCmd.32")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksPassword = argument;
+ }
+ });
+ options.add(new Option(Main.PROVIDER_OPT,
+ Messages.getString("SelfCertCmd.33"), //$NON-NLS-1$
+ Messages.getString("SelfCertCmd.34")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _providerClassName = argument;
+ }
+ });
+ options.add(new Option(Main.VERBOSE_OPT,
+ Messages.getString("SelfCertCmd.35")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ verbose = true;
+ }
+ });
+ result.add(options);
+
+ log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$
+ return result;
+ }
+
private void setDName(String name, X500Principal defaultName)
{
if (name != null && name.trim().length() > 0)
diff --git a/tools/gnu/classpath/tools/keytool/StorePasswdCmd.java b/tools/gnu/classpath/tools/keytool/StorePasswdCmd.java
index 1eb053c1c..6c4dfddb9 100644
--- a/tools/gnu/classpath/tools/keytool/StorePasswdCmd.java
+++ b/tools/gnu/classpath/tools/keytool/StorePasswdCmd.java
@@ -39,6 +39,11 @@ exception statement from your version. */
package gnu.classpath.tools.keytool;
import gnu.classpath.SystemProperties;
+import gnu.classpath.tools.getopt.ClasspathToolParser;
+import gnu.classpath.tools.getopt.Option;
+import gnu.classpath.tools.getopt.OptionException;
+import gnu.classpath.tools.getopt.OptionGroup;
+import gnu.classpath.tools.getopt.Parser;
import java.io.IOException;
import java.security.KeyStoreException;
@@ -65,7 +70,7 @@ import javax.security.auth.callback.UnsupportedCallbackException;
* designated key store.
* <p></dd>
*
- * <dt>-storetype STORE_TYP}</dt>
+ * <dt>-storetype STORE_TYPE</dt>
* <dd>Use this option to specify the type of the key store to use. The
* default value, if this option is omitted, is that of the property
* <code>keystore.type</code> in the security properties file, which is
@@ -107,11 +112,11 @@ import javax.security.auth.callback.UnsupportedCallbackException;
class StorePasswdCmd extends Command
{
private static final Logger log = Logger.getLogger(StorePasswdCmd.class.getName());
- private String _newPassword;
- private String _ksType;
- private String _ksURL;
- private String _ksPassword;
- private String _providerClassName;
+ protected String _newPassword;
+ protected String _ksType;
+ protected String _ksURL;
+ protected String _ksPassword;
+ protected String _providerClassName;
private char[] newStorePasswordChars;
// default 0-arguments constructor
@@ -150,46 +155,14 @@ class StorePasswdCmd extends Command
// life-cycle methods -------------------------------------------------------
- int processArgs(String[] args, int i)
- {
- int limit = args.length;
- String opt;
- while (++i < limit)
- {
- opt = args[i];
- log.finest("args[" + i + "]=" + opt); //$NON-NLS-1$ //$NON-NLS-2$
- if (opt == null || opt.length() == 0)
- continue;
-
- if ("-new".equals(opt)) // -new PASSWORD //$NON-NLS-1$
- _newPassword = args[++i];
- else if ("-storetype".equals(opt)) // -storetype STORE_TYPE //$NON-NLS-1$
- _ksType = args[++i];
- else if ("-keystore".equals(opt)) // -keystore URL //$NON-NLS-1$
- _ksURL = args[++i];
- else if ("-storepass".equals(opt)) // -storepass PASSWORD //$NON-NLS-1$
- _ksPassword = args[++i];
- else if ("-provider".equals(opt)) // -provider PROVIDER_CLASS_NAME //$NON-NLS-1$
- _providerClassName = args[++i];
- else if ("-v".equals(opt)) //$NON-NLS-1$
- verbose = true;
- else
- break;
- }
-
- return i;
- }
-
void setup() throws Exception
{
setKeyStoreParams(_providerClassName, _ksType, _ksPassword, _ksURL);
setNewKeystorePassword(_newPassword);
log.finer("-storepasswd handler will use the following options:"); //$NON-NLS-1$
- log.finer(" -new=" + String.valueOf(newStorePasswordChars)); //$NON-NLS-1$
log.finer(" -storetype=" + storeType); //$NON-NLS-1$
log.finer(" -keystore=" + storeURL); //$NON-NLS-1$
- log.finer(" -storepass=" + String.valueOf(storePasswordChars)); //$NON-NLS-1$
log.finer(" -provider=" + provider); //$NON-NLS-1$
log.finer(" -v=" + verbose); //$NON-NLS-1$
}
@@ -206,6 +179,73 @@ class StorePasswdCmd extends Command
// own methods --------------------------------------------------------------
+ Parser getParser()
+ {
+ log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$
+
+ Parser result = new ClasspathToolParser(Main.STOREPASSWD_CMD, true);
+ result.setHeader(Messages.getString("StorePasswdCmd.18")); //$NON-NLS-1$
+ result.setFooter(Messages.getString("StorePasswdCmd.17")); //$NON-NLS-1$
+ OptionGroup options = new OptionGroup(Messages.getString("StorePasswdCmd.16")); //$NON-NLS-1$
+ options.add(new Option(Main.NEW_OPT,
+ Messages.getString("StorePasswdCmd.15"), //$NON-NLS-1$
+ Messages.getString("StorePasswdCmd.8")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _newPassword = argument;
+ }
+ });
+ options.add(new Option(Main.STORETYPE_OPT,
+ Messages.getString("StorePasswdCmd.13"), //$NON-NLS-1$
+ Messages.getString("StorePasswdCmd.12")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksType = argument;
+ }
+ });
+ options.add(new Option(Main.KEYSTORE_OPT,
+ Messages.getString("StorePasswdCmd.11"), //$NON-NLS-1$
+ Messages.getString("StorePasswdCmd.10")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksURL = argument;
+ }
+ });
+ options.add(new Option(Main.STOREPASS_OPT,
+ Messages.getString("StorePasswdCmd.9"), //$NON-NLS-1$
+ Messages.getString("StorePasswdCmd.8")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _ksPassword = argument;
+ }
+ });
+ options.add(new Option(Main.PROVIDER_OPT,
+ Messages.getString("StorePasswdCmd.7"), //$NON-NLS-1$
+ Messages.getString("StorePasswdCmd.6")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ _providerClassName = argument;
+ }
+ });
+ options.add(new Option(Main.VERBOSE_OPT,
+ Messages.getString("StorePasswdCmd.5")) //$NON-NLS-1$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ verbose = true;
+ }
+ });
+ result.add(options);
+
+ log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$
+ return result;
+ }
+
protected void setNewKeystorePassword(String password) throws IOException,
UnsupportedCallbackException
{
diff --git a/tools/gnu/classpath/tools/keytool/keytool.txt b/tools/gnu/classpath/tools/keytool/keytool.txt
deleted file mode 100644
index 15f9b96f9..000000000
--- a/tools/gnu/classpath/tools/keytool/keytool.txt
+++ /dev/null
@@ -1,616 +0,0 @@
-NAME
- keytool - manage private keys and public certificates
-
-SYNOPSIS
- keytool [COMMAND]...
-
-DESCRIPTION
- A Java-based tool for managing both Key Entries as well as Trusted
- Certificates.
-
- Multiple COMMANDs may be specified at once, each complete with its own
- options. keytool will parse all the arguments, before processing, and
- executing, each COMMAND. If an exception occurs while executing one
- COMMAND keytool will abort.
-
- A COMMAND can be one of the followings:
-
- -genkey [OPTION]...
- Generate a new Key Entry, eventually creating a new key store.
-
- -import [OPTION]...
- Add, to a key store, Key Entries (private keys and certificate
- chains authenticating the public keys) and Trusted Certificates
- (3rd party certificates which can be used as Trust anchors when
- building chains-of-trust).
-
- -selfcert [OPTION]...
- Generate a new self-signed Trusted Certificate.
-
- -identitydb [OPTION]...
- NOT IMPLEMENTED YET.
- Import a JDK 1.1 style Identity Database.
-
- -certreq [OPTION]...
- Issue a Certificate Signing Request (CSR) which can be then sent
- to a Certification Authority (CA) to issue a certificate signed
- (by the CA) and authenticating the Subject of the request.
-
- -export [OPTION]...
- Export a Certificate from a key store.
-
- -list [OPTION]...
- Print one or all Certificates in a key store to STDOUT.
-
- -printcert [OPTION]...
- Print a human-readable form of a Certificate in a designated
- file to STDOUT.
-
- -keyclone [OPTION]...
- Clone a Key Entry in a key store.
-
- -storepasswd [OPTION]...
- Change the password protecting a key store.
-
- -keypasswd [OPTION]...
- Change the password protecting a Key Entry in a key store.
-
- -delete [OPTION]...
- Delete a Key Entry or a Trusted Certificate from a key store.
-
- -help Display this text.
-
-OPTIONS COMMON TO MORE THAN ONE COMMAND
- The following OPTIONs are used in more than one COMMAND. They are
- described here to reduce redundancy.
-
- -alias ALIAS
- Every entry, be it a Key Entry or a Trusted Certificate, in a
- key store is uniquely identified by a user-defined Alias string.
- Use this option to specify the Alias to use when referring to an
- entry in the key store. Unless specified otherwise, a default
- value of "mykey" (all lower case, without the enclosing quotes)
- shall be used when this option is omitted from the command line.
-
- -keyalg ALGORITHM
- Use this option to specify the canonical name of the key-pair
- generation algorithm. The default value for this option is
- "DSS" (a synonym for the Digital Signature Algorithm also known
- as DSA).
-
- -keysize SIZE
- Use this option to specify the number of bits of the shared
- modulus (for both the public and private keys) to use when
- generating new keys. A default value of 1024 will be used if
- this option is omitted from the command line.
-
- -validity DAY_COUNT
- Use this option to specify the number of days a newly generated
- certificate will be valid for. The default value is 90 (days)
- if this option is omitted from the command line.
-
- -storetype STORE_TYPE
- Use this option to specify the type of the key store to use.
- The default value, if this option is omitted, is that of the
- property "keystore.type" in the security properties file, which
- is obtained by invoking the static method call getDefaultType()
- in java.security.KeyStore.
-
- -storepass PASSWORD
- Use this option to specify the password protecting the key
- store. If this option is omitted from the command line, you
- will be prompted to provide a password.
-
- -keystore URL
- Use this option to specify the location of the key store to use.
- The default value is a file URL referencing the file named
- ".keystore" (all lower case and without the enclosing quotes)
- located in the path returned by the call to
- java.lang.System#getProperty(String) using "user.home" as
- argument.
-
- If a URL was specified, but was found to be malformed --e.g.
- missing protocol element-- the tool will attempt to use the URL
- value as a file-name (with absolute or relative path-name) of a
- key store --as if the protocol was "file:".
-
- -provider PROVIDER_CLASS_NAME
- A fully qualified class name of a Security Provider to add to
- the current list of Security Providers already installed in the
- JVM in-use. If a provider class is specified with this option,
- and was successfully added to the runtime --i.e. it was not
- already installed-- then the tool will attempt to remove this
- Security Provider before exiting.
-
- -file FILE_NAME
- Use this option to designate a file to use with a command. When
- specified with this option, the value is expected to be the
- fully qualified path of a file accessible by the File System.
- Depending on the command, the file may be used as input or as
- output. When this option is omitted from the command line,
- STDIN will be used instead, as the source of input, and STDOUT
- will be used instead as the output destination.
-
- -v Unless specified otherwise, use this option to enable more
- verbose output.
-
-X.500 DISTINGUISHED NAME
- A Distinguished Name (or DN) MUST be supplied with some of the COMMANDs
- using a -dname option. The syntax of a valid value for this option MUST
- follow RFC-2253 specifications. Namely the following components (with
- their accepted meaning) will be recognized. Note that the component
- name is case-insensitive:
-
- CN The Common Name; e.g. "host.domain.com"
- OU The Organizational Unit; e.g. "IT Department"
- O The Organization Name; e.g. "The Sample Company"
- L The Locality Name; e.g. "Sydney"
- ST The State Name; e.g. "New South Wales"
- C The 2-letter Country identifier; e.g. "AU"
-
- When specified with a -dname option, each pair of component/value will
- be separated from the other with a comma. Each component and value pair
- MUST be separated by an equal sign. For example, the following is
- a valid DN value:
-
- CN=host.domain.com, O=The Sample Company, L=Sydney, ST=NSW, C=AU
-
- If the Distinguished Name is required, and no valid default value can be
- used, the tool will prompt you to enter the information through the
- console.
-
--genkey COMMAND
- Generate a new key-pair (both private and public keys), and save these
- credentials in the key store as a Key Entry, associated with the
- designated (if was specified in the -alias option) or default (if the
- -alias option is omitted) Alias.
-
- The private key material will be protected with a user-defined password
- (see -keypass option). The public key on the other hand will be part
- of a self-signed X.509 certificate, which will form a 1-element chain
- and will be saved in the key store.
-
- -alias ALIAS
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -keyalg ALGORITHM
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -keysize KEY_SIZE
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -sigalg ALGORITHM
- The canonical name of the digital signature algorithm to use for
- signing certificates. If this option is omitted, a default
- value will be chosen based on the type of the key-pair; i.e. the
- algorithm that ends up being used by the -keyalg option. If the
- key-pair generation algorithm is "DSA", the value for the
- signature algorithm will be "SHA1withDSA". If on the other hand
- the key-pair generation algorithm is "RSA", then the tool will
- use "MD5withRSA" as the signature algorithm.
-
- -dname NAME
- This a mandatory value for the command. If no value is
- specified --i.e. the -dname option is omitted-- the tool will
- prompt you to enter a Distinguished Name to use as both the
- Owner and Issuer of the generated self-signed certificate.
-
- (see X.500 DISTINGUISHED NAME)
-
- -keypass PASSWORD
- Use this option to specify the password which the tool will use
- to protect the newly created Key Entry.
-
- If this option is omitted, you will be prompted to provide a
- password.
-
- -validity DAY_COUNT
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -storetype STORE_TYPE
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -keystore URL
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -storepass PASSWORD
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -provider PROVIDER_CLASS_NAME
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -v (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
--import COMMAND
- Read an X.509 certificate, or a PKCS#7 Certificate Reply from a
- designated input source and incorporate the certificates into the key
- store.
-
- If the Alias does not already exist in the key store, the tool treats
- the certificate read from the input source as a new Trusted Certificate.
- It then attempts to discover a chain-of-trust, starting from that
- certificate and ending at another Trusted Certificate, already stored in
- the key store. If the -trustcacerts option is present, an additional
- key store, of type "JKS" named "cacerts", and assumed to be present in
- ${JAVA_HOME}/lib/security will also be consulted if found --${JAVA_HOME}
- refers to the location of an installed Java Runtime Environment (JRE).
- If no chain-of-trust can be established, and unless the -noprompt option
- has been specified, the certificate is printed to STDOUT and the user is
- prompted for a confirmation.
-
- If Alias exists in the key store, the tool will treat the certificate(s)
- read from the input source as a Certificate Reply, which can be a chain
- of certificates, that eventually would replace the chain of certificates
- associated with the Key Entry of that Alias. The substitution of the
- certificates only occurs if a chain-of-trust can be established between
- the bottom certificate of the chain read from the input file and the
- Trusted Certificates already present in the key store. Again, if the
- -trustcacerts option is specified, additional Trusted Certificates in
- the same "cacerts" key store will be considered. If no chain-of-trust
- can be established, the operation will abort.
-
- -alias ALIAS
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -file FILE_NAME
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -keypass PASSWORD
- Use this option to specify the password which the tool will use
- to protect the Key Entry associated with the designated Alias,
- when replacing this Alias' chain of certificates with that found
- in the certificate reply.
-
- If this option is omitted, and the chain-of-trust for the
- certificate reply has been established, the tool will first
- attempt to unlock the Key Entry using the same password
- protecting the key store. If this fails, you will then be
- prompted to provide a password.
-
- -noprompt
- Use this option to prevent the tool from prompting the user.
-
- -trustcacerts
- Use this option to indicate to the tool that a key store, of
- type "JKS", named "cacerts", and usually located in lib/security
- in an installed Java Runtime Environment should be considered
- when trying to establish chain-of-trusts.
-
- -storetype STORE_TYPE
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -keystore URL
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -storepass PASSWORD
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -provider PROVIDER_CLASS_NAME
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -v (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
--selfcert COMMAND
- Generate a self-signed X.509 version 1 certificate. The newly generated
- certificate will form a chain of one element which will replace the
- previous chain associated with the designated Alias (if -alias option
- was specified), or the default Alias (if -alias option was omitted).
-
- -alias ALIAS
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -sigalg ALGORITHM
- The canonical name of the digital signature algorithm to use for
- signing the certificate. If this option is omitted, a default
- value will be chosen based on the type of the private key
- associated with the designated Alias. If the private key is a
- "DSA" one, the value for the signature algorithm will be
- "SHA1withDSA". If on the other hand the private key is an "RSA"
- one, then the tool will use "MD5withRSA" as the signature
- algorithm.
-
- -dname NAME
- Use this option to specify the Distinguished Name of the newly
- generated self-signed certificate. If this option is omitted,
- the existing Distinguished Name of the base certificate in the
- chain associated with the designated Alias will be used instead.
-
- (see X.500 DISTINGUISHED NAME)
-
- -validity DAY_COUNT
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -keypass PASSWORD
- Use this option to specify the password which the tool will use
- to unlock the Key Entry associated with the designated Alias.
-
- If this option is omitted, the tool will first attempt to unlock
- the Key Entry using the same password protecting the key store.
- If this fails, you will then be prompted to provide a password.
-
- -storetype STORE_TYPE
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -keystore URL
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -storepass PASSWORD
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -provider PROVIDER_CLASS_NAME
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -v (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
--identitydb COMMAND
- NOT IMPLEMENTED YET.
-
- Import a JDK 1.1 style Identity Database.
-
- -file FILE_NAME
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -storetype STORE_TYPE
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -keystore URL
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -storepass PASSWORD
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -provider PROVIDER_CLASS_NAME
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -v (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
--certreq COMMAND
- Generate a PKCS#10 Certificate Signing Request (CSR) and writes it to
- a designated output destination. The contents of the destination
- should look something like the following:
-
- -----BEGIN NEW CERTIFICATE REQUEST-----
- MIICYTCCAiECAQAwXzEUMBIGA1UEAwwLcnNuQGdudS5vcmcxGzAZBgNVBAoMElUg
- Q29tcGFueTEPMA0GA1UEBwwGU3lkbmV5MQwwCgYDVQQIDANOU1cxCzAJBgNVBACC
- ...
- FCTlKlok8KwGuIVwNVOfQLRX+O5kAhQ/a4RTZme2L8PnpvgRwrf7Eg8D6w==
- -----END NEW CERTIFICATE REQUEST-----
-
- IMPORTANT: Some documentation (e.g. RSA examples) claims that the
- Attributes field, in the CSR is OPTIONAL while RFC-2986 implies the
- opposite. This implementation considers this field, by default, as
- OPTIONAL, unless the option -attributes is specified on the command
- line.
-
- -alias ALIAS
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -sigalg ALGORITHM
- The canonical name of the digital signature algorithm to use for
- signing the certificate. If this option is omitted, a default
- value will be chosen based on the type of the private key
- associated with the designated Alias. If the private key is a
- "DSA" one, the value for the signature algorithm will be
- "SHA1withDSA". If on the other hand the private key is an "RSA"
- one, then the tool will use "MD5withRSA" as the signature
- algorithm.
-
- -file FILE_NAME
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -keypass PASSWORD
- Use this option to specify the password which the tool will use
- to unlock the Key Entry associated with the designated Alias.
-
- If this option is omitted, the tool will first attempt to unlock
- the Key Entry using the same password protecting the key store.
- If this fails, you will then be prompted to provide a password.
-
- -storetype STORE_TYPE
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -keystore URL
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -storepass PASSWORD
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -provider PROVIDER_CLASS_NAME
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -v (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -attributes
- Use this option to force the tool to encode a NULL DER value in
- the CSR as the value of the Attributes field.
-
--export COMMAND
- Export a certificate stored in the key store to a designated output
- destination, either in binary format (if the -v option is specified),
- or in RFC-1421 compliant encoding (if the -rfc option is specified
- instead).
-
- -alias ALIAS
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -file FILE_NAME
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -storetype STORE_TYPE
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -keystore URL
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -storepass PASSWORD
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -provider PROVIDER_CLASS_NAME
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -rfc Use RFC-1421 specifications when encoding the output.
-
- -v Output the certificate in binary DER encoding. This is the
- default output format of the command if neither -rfc nor -v
- options were detected on the command line. If both this option
- and the -rfc option are detected on the command line, the tool
- will opt for the RFC-1421 style encoding.
-
--list COMMAND
- Print one or all of the key store entries to STDOUT. Usually this
- command will only print a fingerprint of the certificate, unless either
- the -rfc or the -v option is specified.
-
- -alias ALIAS
- If this option is omitted, the tool will print ALL the entries
- found in the key store.
-
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -storetype STORE_TYPE
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -keystore URL
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -storepass PASSWORD
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -provider PROVIDER_CLASS_NAME
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -rfc Use RFC-1421 specifications when encoding the output.
-
- -v Output the certificate in human-readable format. If both this
- option and the -rfc option are detected on the command line,
- the tool will opt for the human-readable form and will not
- abort the command.
-
--printcert COMMAND
- Read a certificate from a designated input source and print it to STDOUT
- in a human-readable form.
-
- -file FILE_NAME
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -v (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
--keyclone COMMAND
- Clone an existing Key Entry and store it under a new (different) Alias
- protecting, its private key material with possibly a new password.
-
- -alias ALIAS
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -dest ALIAS
- Use this option to specify the new Alias which will be used to
- identify the cloned copy of the Key Entry.
-
- -keypass PASSWORD
- Use this option to specify the password which the tool will use
- to unlock the Key Entry associated with the designated Alias.
-
- If this option is omitted, the tool will first attempt to unlock
- the Key Entry using the same password protecting the key store.
- If this fails, you will then be prompted to provide a password.
-
- -new PASSWORD
- Use this option to specify the password protecting the private
- key material of the newly cloned copy of the Key Entry.
-
- -storetype STORE_TYPE
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -keystore URL
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -storepass PASSWORD
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -provider PROVIDER_CLASS_NAME
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -v (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
--storepasswd COMMAND
- Change the password protecting a key store.
-
- -new PASSWORD
- The new, and different, password which will be used to protect
- the designated key store.
-
- -storetype STORE_TYPE
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -keystore URL
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -storepass PASSWORD
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -provider PROVIDER_CLASS_NAME
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -v (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
--keypasswd COMMAND
- Change the password protecting the private key material of a designated
- Key Entry.
-
- -alias ALIAS
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -keypass PASSWORD
- Use this option to specify the password which the tool will use
- to unlock the Key Entry associated with the designated Alias.
-
- If this option is omitted, the tool will first attempt to unlock
- the Key Entry using the same password protecting the key store.
- If this fails, you will then be prompted to provide a password.
-
- -new PASSWORD
- The new, and different, password which will be used to protect
- the private key material of the designated Key Entry.
-
- -storetype STORE_TYPE
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -keystore URL
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -storepass PASSWORD
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -provider PROVIDER_CLASS_NAME
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -v (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
--delete COMMAND
- Delete a designated key store entry.
-
- -alias ALIAS
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -storetype STORE_TYPE
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -keystore URL
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -storepass PASSWORD
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -provider PROVIDER_CLASS_NAME
- (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
- -v (see OPTIONS COMMON TO MORE THAN ONE COMMAND)
-
-REPORTING BUGS
- Please report bugs at http://www.gnu.org/software/classpath/bugs.html
-
-COPYRIGHT
- Copyright (C) 2006 Free Software Foundation, Inc.
- This is free software; see the source for copying conditions. There is
- NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE.
diff --git a/tools/gnu/classpath/tools/native2ascii/Messages.java b/tools/gnu/classpath/tools/native2ascii/Messages.java
new file mode 100644
index 000000000..4c6bae4dc
--- /dev/null
+++ b/tools/gnu/classpath/tools/native2ascii/Messages.java
@@ -0,0 +1,67 @@
+/* Messages.java -- translation support for native2ascii
+ 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.native2ascii;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class Messages
+{
+ private static final String BUNDLE_NAME
+ = "gnu.classpath.tools.native2ascii.messages"; //$NON-NLS-1$
+
+ private static final ResourceBundle RESOURCE_BUNDLE
+ = ResourceBundle.getBundle(BUNDLE_NAME);
+
+ private Messages()
+ {
+ }
+
+ public static String getString(String key)
+ {
+ try
+ {
+ return RESOURCE_BUNDLE.getString(key);
+ }
+ catch (MissingResourceException e)
+ {
+ return '!' + key + '!';
+ }
+ }
+}
diff --git a/tools/gnu/classpath/tools/native2ascii/Native2ASCII.java b/tools/gnu/classpath/tools/native2ascii/Native2ASCII.java
new file mode 100644
index 000000000..9508c103e
--- /dev/null
+++ b/tools/gnu/classpath/tools/native2ascii/Native2ASCII.java
@@ -0,0 +1,185 @@
+/* Native2ASCII.java - native2ascii program
+ Copyright (C) 2003 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.native2ascii;
+
+import gnu.classpath.tools.getopt.ClasspathToolParser;
+import gnu.classpath.tools.getopt.FileArgumentCallback;
+import gnu.classpath.tools.getopt.Option;
+import gnu.classpath.tools.getopt.OptionException;
+import gnu.classpath.tools.getopt.Parser;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+
+/**
+ * Native2ASCII main program.
+ * @author Ito Kazumitsu <kaz@maczuka.gcd.org>
+ */
+public class Native2ASCII
+{
+ // Input file.
+ String input;
+ // Output file.
+ String output;
+ // Encoding to use.
+ String encoding;
+ // True for reverse operation.
+ boolean reversed;
+
+ private class HandleFile extends FileArgumentCallback
+ {
+ public HandleFile()
+ {
+ }
+
+ public void notifyFile(String fileArgument)
+ throws OptionException
+ {
+ if (input == null)
+ input = fileArgument;
+ else if (output == null)
+ output = fileArgument;
+ else
+ throw new OptionException(Messages.getString("Native2ASCII.TooManyFiles")); //$NON-NLS-1$
+ }
+ }
+
+ private Parser createParser()
+ {
+ Parser result = new ClasspathToolParser("native2ascii", true); //$NON-NLS-1$
+ result.setHeader(Messages.getString("Native2ASCII.Usage")); //$NON-NLS-1$
+
+ result.add(new Option("encoding", Messages.getString("Native2ASCII.EncodingHelp"), Messages.getString("Native2ASCII.EncodingArgName")) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ if (encoding != null)
+ throw new OptionException(Messages.getString("Native2ASCII.EncodingSpecified")); //$NON-NLS-1$
+ encoding = argument;
+ }
+ });
+ result.add(new Option("reversed", Messages.getString("Native2ASCII.ReversedHelp")) //$NON-NLS-1$ //$NON-NLS-2$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ reversed = true;
+ }
+ });
+
+ return result;
+ }
+
+ private void run(String[] args)
+ {
+ Parser argParser = createParser();
+ argParser.parse(args, new HandleFile());
+
+ if (encoding == null)
+ encoding = System.getProperty("file.encoding"); //$NON-NLS-1$
+ try
+ {
+ InputStream is = (input == null ? System.in
+ : new FileInputStream(input));
+ OutputStream os = (output == null ? (OutputStream) System.out
+ : new FileOutputStream(output));
+
+ BufferedReader rdr = new BufferedReader(new InputStreamReader(is,
+ encoding));
+ PrintWriter wtr = new PrintWriter(
+ new BufferedWriter(
+ new OutputStreamWriter(
+ os,
+ encoding)));
+ while (true)
+ {
+ String s = rdr.readLine();
+ if (s == null)
+ break;
+ StringBuffer sb = new StringBuffer(s.length() + 80);
+ for (int i = 0; i < s.length(); i++)
+ {
+ char c = s.charAt(i);
+ if (reversed
+ && i + 6 < s.length()
+ && s.charAt(i) == '\\'
+ && s.charAt(i + 1) == 'u')
+ {
+ int num = Integer.parseInt(s.substring(i + 2, i + 6), 16);
+ sb.append((char) num);
+ i += 5;
+ }
+ else if ((int)c <= 127 || reversed)
+ {
+ sb.append(c);
+ }
+ else
+ {
+ sb.append("\\u"); //$NON-NLS-1$
+ if ((int)c <= 0xff)
+ sb.append("00"); //$NON-NLS-1$
+ else if ((int)c <= 0xfff)
+ sb.append("0"); //$NON-NLS-1$
+ sb.append(Integer.toHexString((int) c));
+ }
+ }
+ wtr.println(sb.toString());
+ }
+ rdr.close();
+ wtr.flush();
+ wtr.close();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ new Native2ASCII().run(args);
+ String encoding = System.getProperty("file.encoding"); //$NON-NLS-1$
+ }
+}
diff --git a/tools/gnu/classpath/tools/rmi/RMIC.java b/tools/gnu/classpath/tools/rmi/RMIC.java
index c44453011..fa4d87c17 100644
--- a/tools/gnu/classpath/tools/rmi/RMIC.java
+++ b/tools/gnu/classpath/tools/rmi/RMIC.java
@@ -41,7 +41,7 @@ public class RMIC
/**
* The version of the compiler.
*/
- public static String VERSION = "0.0 alpha pre";
+ public static String VERSION = "0.01 alpha pre";
/**
* The GRMIC compiler methods
@@ -112,6 +112,17 @@ public class RMIC
else
HelpPrinter.printHelpAndExit(HelpPath);
}
+ else if (c.equals("-classpath"))
+ {
+ int f = i + 1;
+ if (f < args.length)
+ {
+ compiler.setClassPath(args[f]);
+ i++;
+ }
+ else
+ HelpPrinter.printHelpAndExit(HelpPath);
+ }
else if (c.charAt(0) != '-')
// No more options - start of class list.
{
@@ -132,17 +143,7 @@ public class RMIC
if (args[i].charAt(0) != '-')
{
compiler.reset();
- Class c = null;
- try
- {
- c = Thread.currentThread().getContextClassLoader().loadClass(
- args[i]);
- }
- catch (ClassNotFoundException e)
- {
- System.err.println(args[i] + " class not found.");
- System.exit(1);
- }
+ Class c = compiler.loadClass(args[i]);
compiler.compile(c);
String packag = compiler.getPackageName().replace('.', '/');
diff --git a/tools/gnu/classpath/tools/rmi/RMIC.txt b/tools/gnu/classpath/tools/rmi/RMIC.txt
index 7ec371e9a..882cca553 100644
--- a/tools/gnu/classpath/tools/rmi/RMIC.txt
+++ b/tools/gnu/classpath/tools/rmi/RMIC.txt
@@ -9,25 +9,29 @@ Please report bugs at http://www.gnu.org/software/classpath/bugs.html
Usage: rmic <options> <class names>
where <options> includes:
- -nowarn Show no warnings
- -nowrite Do not write any files (check for errors only)
- -d <folder> Place generated files into the given folder
+ -nowarn Show no warnings
+ -nowrite Do not write any files (check for errors only)
+ -d <folder> Place generated files into the given folder
+ -classpath <path> Specifies the path, where to find the classes being
+ compiled
- -help Print this help text
- -v Print version
- -verbose Verbose output
- -force Try to generate code even if the input classes seem not
- consistent with RMI specification.
+ -help Print this help text
+ -v Print version
+ -verbose Verbose output
+ -force Try to generate code even if the input classes seem not
+ consistent with RMI specification.
- -1.2 Generate v 1.2 stubs (default)*
+ -1.2 Generate v 1.2 stubs (default)*
- -iiop Generate stubs and ties for the GIOP based RMI package extension,
- javax.rmi. With this key, the two additional keys are accepted:
- -poa Generate the Servant based ties (default)
- -impl Generate the obsoleted ObjectImpl based ties
- (for backward compatibility)
- -help Show more details on the giop stub and tie generator options.
- -giop Same as -iiop*
+ -iiop Generate stubs and ties for the GIOP based RMI package
+ extension, javax.rmi. With this key, the two additional
+ keys are accepted:
+ -poa Generate the Servant based ties (default)
+ -impl Generate the obsoleted ObjectImpl based ties
+ (for backward compatibility)
+ -help Show more details on the giop stub and tie generator
+ options.
+ -giop Same as -iiop*
and <class names> can include one or more non abstract classes that implement
diff --git a/tools/gnu/classpath/tools/serialver/Messages.java b/tools/gnu/classpath/tools/serialver/Messages.java
new file mode 100644
index 000000000..a6ab67add
--- /dev/null
+++ b/tools/gnu/classpath/tools/serialver/Messages.java
@@ -0,0 +1,68 @@
+/* Messages.java -- translations for serialver tool
+ 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.serialver;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class Messages
+{
+ private static final String BUNDLE_NAME
+ = "gnu.classpath.tools.serialver.messages"; //$NON-NLS-1$
+
+ private static final ResourceBundle RESOURCE_BUNDLE
+ = ResourceBundle.getBundle(BUNDLE_NAME);
+
+ private Messages()
+ {
+ }
+
+ public static String getString(String key)
+ {
+ // TODO Auto-generated method stub
+ try
+ {
+ return RESOURCE_BUNDLE.getString(key);
+ }
+ catch (MissingResourceException e)
+ {
+ return '!' + key + '!';
+ }
+ }
+}
diff --git a/tools/gnu/classpath/tools/serialver/SerialVer.java b/tools/gnu/classpath/tools/serialver/SerialVer.java
new file mode 100644
index 000000000..b5a12ec92
--- /dev/null
+++ b/tools/gnu/classpath/tools/serialver/SerialVer.java
@@ -0,0 +1,163 @@
+/* gnu.classpath.tools.SerialVer
+ Copyright (C) 1998, 1999, 2000, 2001 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.serialver;
+
+import gnu.classpath.tools.getopt.ClasspathToolParser;
+import gnu.classpath.tools.getopt.FileArgumentCallback;
+import gnu.classpath.tools.getopt.Option;
+import gnu.classpath.tools.getopt.OptionException;
+import gnu.classpath.tools.getopt.Parser;
+
+import java.io.File;
+import java.io.ObjectStreamClass;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.StringTokenizer;
+
+/**
+ * This class is an implementation of the `serialver' program. Any number of
+ * class names can be passed as arguments, and the serial version unique
+ * identitfier for each class will be printed in a manner suitable for cuting
+ * and pasting into a Java source file.
+ */
+public class SerialVer
+{
+ // List of classes to load.
+ ArrayList classes = new ArrayList();
+ // The class path to use.
+ String classpath;
+
+ // FIXME: taken from ClassLoader, should share it.
+ private static void addFileURL(ArrayList list, String file)
+ {
+ try
+ {
+ list.add(new File(file).toURL());
+ }
+ catch(java.net.MalformedURLException x)
+ {
+ }
+ }
+
+ private ClassLoader getClassLoader()
+ {
+ // FIXME: this code is taken from ClassLoader.
+ // We should share it somewhere.
+ URL[] urls;
+ if (classpath == null)
+ urls = new URL[0];
+ else
+ {
+ StringTokenizer tok = new StringTokenizer(classpath,
+ File.pathSeparator, true);
+ ArrayList list = new ArrayList();
+ while (tok.hasMoreTokens())
+ {
+ String s = tok.nextToken();
+ if (s.equals(File.pathSeparator))
+ addFileURL(list, "."); //$NON-NLS-1$
+ else
+ {
+ addFileURL(list, s);
+ if (tok.hasMoreTokens())
+ {
+ // Skip the separator.
+ tok.nextToken();
+ // If the classpath ended with a separator,
+ // append the current directory.
+ if (!tok.hasMoreTokens())
+ addFileURL(list, "."); //$NON-NLS-1$
+ }
+ }
+ }
+ urls = new URL[list.size()];
+ urls = (URL[]) list.toArray(urls);
+ }
+ return new URLClassLoader(urls);
+ }
+
+ private void printMessage(String format, String klass)
+ {
+ System.err.println(MessageFormat.format(format, new Object[] { klass }));
+ }
+
+ public void run(String[] args)
+ {
+ Parser p = new ClasspathToolParser("serialver", true) //$NON-NLS-1$
+ {
+ protected void validate() throws OptionException
+ {
+ if (classes.isEmpty())
+ throw new OptionException(Messages.getString("SerialVer.NoClassesSpecd")); //$NON-NLS-1$
+ }
+ };
+ p.setHeader(Messages.getString("SerialVer.HelpHeader")); //$NON-NLS-1$
+
+ p.add(new Option(Messages.getString("SerialVer.5"), Messages.getString("SerialVer.ClasspathHelp"), "PATH") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ {
+ public void parsed(String argument) throws OptionException
+ {
+ if (classpath != null)
+ throw new OptionException(Messages.getString("SerialVer.DupClasspath")); //$NON-NLS-1$
+ classpath = argument;
+ }
+ });
+
+ p.parse(args, new FileArgumentCallback()
+ {
+ public void notifyFile(String fileArgument) throws OptionException
+ {
+ classes.add(fileArgument);
+ }
+ });
+
+ ClassLoader loader = getClassLoader();
+ Iterator it = classes.iterator();
+ while (it.hasNext())
+ {
+ String name = (String) it.next();
+ try
+ {
+ Class clazz = loader.loadClass(name);
+ ObjectStreamClass osc = ObjectStreamClass.lookup(clazz);
+ if (osc != null)
+ System.out.println(clazz.getName() + ": " //$NON-NLS-1$
+ + "static final long serialVersionUID = " //$NON-NLS-1$
+ + osc.getSerialVersionUID() + "L;"); //$NON-NLS-1$
+ else
+ printMessage(Messages.getString("SerialVer.ClassNotSerial"), name); //$NON-NLS-1$
+ }
+ catch (ClassNotFoundException e)
+ {
+ printMessage(Messages.getString("SerialVer.ClassNotFound"), name); //$NON-NLS-1$
+ }
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ new SerialVer().run(args);
+ }
+} \ No newline at end of file
diff --git a/tools/jarsigner.in b/tools/jarsigner.in
index cea95a288..537b7faf0 100644
--- a/tools/jarsigner.in
+++ b/tools/jarsigner.in
@@ -44,20 +44,4 @@ prefix=@prefix@
tools_dir=@datadir@/@PACKAGE@
tools_cp=${tools_dir}/tools.zip
-# find the java executable...
-if [ -z "${JAVA}" ] ; then
- if [ -n "${JAVA_HOME}" ] ; then
- if [ -x "${JAVA_HOME}/jre/sh/java" ] ; then
- JAVA="${JAVA_HOME}/jre/sh/java"
- else
- JAVA="${JAVA_HOME}/bin/java"
- fi
- else
- JAVA=`which java 2> /dev/null `
- if [ -z "${JAVA}" ] ; then
- JAVA=java
- fi
- fi
-fi
-
-exec "${JAVA}" -Xbootclasspath/p:"${tools_cp}" gnu.classpath.tools.jarsigner.Main $@
+exec @VM_BINARY@ -Xbootclasspath/p:"${tools_cp}" gnu.classpath.tools.jarsigner.Main $@
diff --git a/tools/keytool.in b/tools/keytool.in
index 6c11dc407..613baf7fd 100644
--- a/tools/keytool.in
+++ b/tools/keytool.in
@@ -44,20 +44,4 @@ prefix=@prefix@
tools_dir=@datadir@/@PACKAGE@
tools_cp=${tools_dir}/tools.zip
-# find the java executable...
-if [ -z "${JAVA}" ] ; then
- if [ -n "${JAVA_HOME}" ] ; then
- if [ -x "${JAVA_HOME}/jre/sh/java" ] ; then
- JAVA="${JAVA_HOME}/jre/sh/java"
- else
- JAVA="${JAVA_HOME}/bin/java"
- fi
- else
- JAVA=`which java 2> /dev/null `
- if [ -z "${JAVA}" ] ; then
- JAVA=java
- fi
- fi
-fi
-
-exec "${JAVA}" -Xbootclasspath/p:"${tools_cp}" gnu.classpath.tools.keytool.Main $@
+exec @VM_BINARY@ -Xbootclasspath/p:"${tools_cp}" gnu.classpath.tools.keytool.Main $@
diff --git a/tools/appletviewer.c b/tools/toolwrapper.c
index 2609ccaf6..de6556c63 100644
--- a/tools/appletviewer.c
+++ b/tools/toolwrapper.c
@@ -1,5 +1,5 @@
-/* appletviewer.c -- a native appletviewer wrapper for VMs that
- support the JNI invocation interface
+/* toolwrapper.c -- a native tool wrapper for VMs that support the JNI
+ invocation interface
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,7 +37,6 @@ obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
#include <jni.h>
-#include <glib.h>
#include <string.h>
#include <stdlib.h>
#include "config.h"
@@ -93,41 +92,27 @@ main (int argc, const char** argv)
if (vm_args.options == NULL)
{
- g_printerr ("appletviewer: realloc failed.\n");
+ fprintf (stderr, TOOLNAME ": realloc failed.\n");
goto destroy;
}
if (strlen (argv[i]) == 2)
{
- g_printerr ("appletviewer: the -J option must not be followed by a space.\n");
+ fprintf (stderr, TOOLNAME ": the -J option must not be followed by a space.\n");
goto destroy;
}
else
- vm_args.options[vm_args.nOptions++].optionString = g_strdup (argv[i] + 2);
- }
- else if (!strncmp (argv[i], "--version", 9)
- && argv[i][9] == '\0')
- {
- g_print ("appletviewer (GCJ Applet Viewer) " PACKAGE_VERSION "\n");
- exit (0);
- }
- else if (!strncmp (argv[i], "-debug", 6)
- && argv[i][6] == '\0')
- {
- /* FIXME: Ignore for now. The debug option will be
- unsupported until we have the ability to debug
- bytecode. For now, just strip it out of the argument
- list. */
+ vm_args.options[vm_args.nOptions++].optionString = strdup (argv[i] + 2);
}
else
{
non_vm_argv = (char**) realloc (non_vm_argv, (non_vm_argc + 1) * sizeof (char*));
if (non_vm_argv == NULL)
{
- g_printerr ("appletviewer: realloc failed.\n");
+ fprintf (stderr, TOOLNAME ": realloc failed.\n");
goto destroy;
}
- non_vm_argv[non_vm_argc++] = g_strdup (argv[i]);
+ non_vm_argv[non_vm_argc++] = strdup (argv[i]);
}
}
}
@@ -139,18 +124,18 @@ main (int argc, const char** argv)
if (vm_args.options == NULL)
{
- g_printerr ("appletviewer: realloc failed.\n");
+ fprintf (stderr, TOOLNAME ": realloc failed.\n");
goto destroy;
}
- vm_args.options[vm_args.nOptions++].optionString = "-Djava.class.path=" "@datadir@/@PACKAGE@/tools.zip";
+ vm_args.options[vm_args.nOptions++].optionString = "-Djava.class.path=" DATA_DIR "/" PACKAGE "/tools.zip";
}
/* Terminate vm_args.options with a NULL element. */
vm_args.options = (JavaVMOption*) realloc (vm_args.options, (vm_args.nOptions + 1) * sizeof (JavaVMOption));
if (vm_args.options == NULL)
{
- g_printerr ("appletviewer: realloc failed.\n");
+ fprintf (stderr, TOOLNAME ": realloc failed.\n");
goto destroy;
}
vm_args.options[vm_args.nOptions].optionString = NULL;
@@ -159,7 +144,7 @@ main (int argc, const char** argv)
non_vm_argv = (char**) realloc (non_vm_argv, (non_vm_argc + 1) * sizeof (char*));
if (non_vm_argv == NULL)
{
- g_printerr ("appletviewer: realloc failed.\n");
+ fprintf (stderr, TOOLNAME ": realloc failed.\n");
goto destroy;
}
non_vm_argv[non_vm_argc] = NULL;
@@ -171,7 +156,7 @@ main (int argc, const char** argv)
if (result < 0)
{
- g_printerr ("appletviewer: couldn't create virtual machine\n");
+ fprintf (stderr, TOOLNAME ": couldn't create virtual machine\n");
goto destroy;
}
@@ -180,14 +165,14 @@ main (int argc, const char** argv)
string_class_id = (*env)->FindClass (env, "java/lang/String");
if (string_class_id == NULL)
{
- g_printerr ("appletviewer: FindClass failed.\n");
+ fprintf (stderr, TOOLNAME ": FindClass failed.\n");
goto destroy;
}
args_array = (*env)->NewObjectArray (env, non_vm_argc, string_class_id, NULL);
if (args_array == NULL)
{
- g_printerr ("appletviewer: NewObjectArray failed.\n");
+ fprintf (stderr, TOOLNAME ": NewObjectArray failed.\n");
goto destroy;
}
@@ -196,17 +181,17 @@ main (int argc, const char** argv)
str = (*env)->NewStringUTF (env, non_vm_argv[i]);
if (str == NULL)
{
- g_printerr ("appletviewer: NewStringUTF failed.\n");
+ fprintf (stderr, TOOLNAME ": NewStringUTF failed.\n");
goto destroy;
}
(*env)->SetObjectArrayElement (env, args_array, i, str);
}
- class_id = (*env)->FindClass (env, "gnu/classpath/tools/appletviewer/Main");
+ class_id = (*env)->FindClass (env, "gnu/classpath/tools/" TOOLNAME "/Main");
if (class_id == NULL)
{
- g_printerr ("appletviewer: FindClass failed.\n");
+ fprintf (stderr, TOOLNAME ": FindClass failed.\n");
goto destroy;
}
@@ -214,7 +199,7 @@ main (int argc, const char** argv)
if (method_id == NULL)
{
- g_printerr ("appletviewer: GetStaticMethodID failed.\n");
+ fprintf (stderr, TOOLNAME ": GetStaticMethodID failed.\n");
goto destroy;
}
diff --git a/vm/reference/gnu/java/nio/VMChannel.java b/vm/reference/gnu/java/nio/VMChannel.java
new file mode 100644
index 000000000..fdea8ff62
--- /dev/null
+++ b/vm/reference/gnu/java/nio/VMChannel.java
@@ -0,0 +1,197 @@
+/* VMChannel.java -- Native interface suppling channel operations.
+ 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.java.nio;
+
+import gnu.classpath.Configuration;
+import gnu.java.net.PlainSocketImpl;
+import gnu.java.nio.PipeImpl.SinkChannelImpl;
+import gnu.java.nio.PipeImpl.SourceChannelImpl;
+import gnu.java.nio.channels.FileChannelImpl;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * Native interface to support configuring of channel to run in a non-blocking
+ * manner and support scatter/gather io operations.
+ *
+ * @author Michael Barker <mike@middlesoft.co.uk>
+ *
+ */
+public class VMChannel
+{
+ private final int fd;
+
+ private VMChannel(int fd)
+ {
+ this.fd = fd;
+ }
+
+ public static VMChannel getVMChannel(PlainSocketImpl socket)
+ {
+ return new VMChannel(socket.getNativeFD());
+ }
+
+ public static VMChannel getVMChannel(SourceChannelImpl source)
+ {
+ return new VMChannel(source.getNativeFD());
+ }
+
+ public static VMChannel getVMChannel(SinkChannelImpl sink)
+ {
+ return new VMChannel(sink.getNativeFD());
+ }
+
+ public static VMChannel getVMChannel(FileChannelImpl file)
+ {
+ return new VMChannel(file.getNativeFD());
+ }
+
+ static
+ {
+ // load the shared library needed for native methods.
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary ("javanio");
+ }
+ initIDs();
+ }
+
+ /**
+ * Set the file descriptor to have the required blocking
+ * setting.
+ *
+ * @param fd
+ * @param blocking
+ */
+ public native void setBlocking(int fd, boolean blocking);
+
+ public void setBlocking(boolean blocking)
+ {
+ setBlocking(fd, blocking);
+ }
+
+
+ /**
+ * Reads a byte buffer directly using the supplied file descriptor.
+ * Assumes that the buffer is a DirectBuffer.
+ *
+ * @param fd Native file descriptor to read from.
+ * @param dst Direct Byte Buffer to read to.
+ * @return Number of bytes read.
+ * @throws IOException If an error occurs or dst is not a direct buffers.
+ */
+ native int read(int fd, ByteBuffer dst)
+ throws IOException;
+
+ public int read(ByteBuffer dst)
+ throws IOException
+ {
+ return read(fd, dst);
+ }
+
+ /**
+ * Reads into byte buffers directly using the supplied file descriptor.
+ * Assumes that the buffer list contains DirectBuffers. Will perform a
+ * scattering read.
+ *
+ * @param fd Native file descriptor to read from.
+ * @param dsts An array direct byte buffers.
+ * @param offset Index of the first buffer to read to.
+ * @param length The number of buffers to read to.
+ * @return Number of bytes read.
+ * @throws IOException If an error occurs or the dsts are not direct buffers.
+ */
+ native long readScattering(int fd, ByteBuffer[] dsts, int offset, int length)
+ throws IOException;
+
+ public long readScattering(ByteBuffer[] dsts, int offset, int length)
+ throws IOException
+ {
+ if (offset + length > dsts.length)
+ throw new IndexOutOfBoundsException("offset + length > dsts.length");
+
+ return readScattering(fd, dsts, offset, length);
+ }
+
+ /**
+ * Writes from a direct byte bufer using the supplied file descriptor.
+ * Assumes the buffer is a DirectBuffer.
+ *
+ * @param fd
+ * @param src
+ * @return Number of bytes written.
+ * @throws IOException
+ */
+ native int write(int fd, ByteBuffer src)
+ throws IOException;
+
+ public int write(ByteBuffer src)
+ throws IOException
+ {
+ return write(fd, src);
+ }
+
+ /**
+ * Writes from byte buffers directly using the supplied file descriptor.
+ * Assumes the that buffer list constains DirectBuffers. Will perform
+ * as gathering write.
+ *
+ * @param fd
+ * @param srcs
+ * @param offset
+ * @param length
+ * @return Number of bytes written.
+ * @throws IOException
+ */
+ native long writeGathering(int fd, ByteBuffer[] srcs, int offset, int length)
+ throws IOException;
+
+ public long writeGathering(ByteBuffer[] srcs, int offset, int length)
+ throws IOException
+ {
+ if (offset + length > srcs.length)
+ throw new IndexOutOfBoundsException("offset + length > srcs.length");
+
+ return writeGathering(fd, srcs, offset, length);
+ }
+
+ private native static void initIDs();
+
+}
diff --git a/vm/reference/java/lang/VMClassLoader.java b/vm/reference/java/lang/VMClassLoader.java
index 4caa58c2a..897df5186 100644
--- a/vm/reference/java/lang/VMClassLoader.java
+++ b/vm/reference/java/lang/VMClassLoader.java
@@ -75,6 +75,10 @@ final class VMClassLoader
/** packages loaded by the bootstrap class loader */
static final HashMap definedPackages = new HashMap();
+ /** jars from property java.boot.class.path */
+ static final HashMap bootjars = new HashMap();
+
+
/**
* Converts the array string of native package names to
* Packages. The packages are then put into the
@@ -168,10 +172,6 @@ final class VMClassLoader
return (URL)e.nextElement();
return null;
}
-
- /** jars from property java.boot.class.path */
- static final HashMap bootjars = new HashMap();
-
/**
* Helper to get a list of resources from the bootstrap class loader.
*
diff --git a/vm/reference/java/net/VMURLConnection.java b/vm/reference/java/net/VMURLConnection.java
new file mode 100644
index 000000000..19bf5814e
--- /dev/null
+++ b/vm/reference/java/net/VMURLConnection.java
@@ -0,0 +1,79 @@
+/* VMURLConnection - VM code for URLConnection
+ 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.classpath.Configuration;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+final class VMURLConnection
+{
+ public static final int LENGTH = 1024;
+
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ System.loadLibrary("javanet");
+ init();
+ }
+
+ private static native void init();
+
+ private static native String guessContentTypeFromBuffer(byte[] b, int valid);
+
+ /**
+ * This is called from URLConnection to guess the mime type of a
+ * stream. This method may return null to indicate that it could
+ * not guess a type.
+ */
+ static String guessContentTypeFromStream(InputStream is)
+ throws IOException
+ {
+ if (! is.markSupported())
+ return null;
+ is.mark(LENGTH);
+ byte[] bytes = new byte[LENGTH];
+ int r = is.read(bytes);
+ if (r < 0)
+ return null;
+ is.reset();
+ return guessContentTypeFromBuffer(bytes, r);
+ }
+}