From 1cd594d11300e2eff0e5addfe6e118b1605afa3d Mon Sep 17 00:00:00 2001 From: Harald Kuhr Date: Mon, 24 Jan 2022 09:01:53 +0100 Subject: [PATCH] RIP: Sandbox --- pom.xml | 1 - sandbox/pom.xml | 156 -- sandbox/sandbox-common/pom.xml | 58 - .../twelvemonkeys/image/AbstractFilter.java | 143 -- .../twelvemonkeys/image/ConvolveTester.java | 128 -- .../com/twelvemonkeys/image/EasyImage.java | 78 - .../image/ExtendedImageConsumer.java | 61 - .../image/GenericWritableRaster.java | 61 - .../twelvemonkeys/image/InstaCRTFilter.java | 182 -- .../twelvemonkeys/image/InstaLomoFilter.java | 201 -- .../twelvemonkeys/image/InstaSepiaFilter.java | 150 -- .../image/MappedBufferImage.java | 1019 ---------- .../twelvemonkeys/image/MappedFileBuffer.java | 174 -- .../image/MappedImageFactory.java | 325 --- .../com/twelvemonkeys/image/NoiseFilter.java | 228 --- .../twelvemonkeys/image/SubsampleTester.java | 163 -- .../java/com/twelvemonkeys/image/inv_cmap.c | 524 ----- .../com/twelvemonkeys/io/FileLockingTest.java | 64 - .../com/twelvemonkeys/io/FileMonitor.java | 57 - .../twelvemonkeys/io/StringInputStream.java | 87 - .../twelvemonkeys/io/enc/DeflateEncoder.java | 90 - .../twelvemonkeys/io/enc/InflateDecoder.java | 110 -- .../java/com/twelvemonkeys/lang/DuckType.java | 468 ----- .../com/twelvemonkeys/lang/ExceptionUtil.java | 89 - .../java/com/twelvemonkeys/lang/MathUtil.java | 138 -- .../lang/MostUnfortunateException.java | 55 - .../com/twelvemonkeys/lang/NativeLoader.java | 401 ---- .../twelvemonkeys/lang/NativeResourceSPI.java | 99 - .../net/AuthenticatorFilter.java | 45 - .../java/com/twelvemonkeys/net/BASE64.java | 143 -- .../twelvemonkeys/net/HttpURLConnection.java | 1101 ----------- .../java/com/twelvemonkeys/net/NetUtil.java | 1258 ------------ .../net/PasswordAuthenticator.java | 45 - .../net/SimpleAuthenticator.java | 270 --- .../twelvemonkeys/sql/DatabaseConnection.java | 247 --- .../twelvemonkeys/sql/DatabaseProduct.java | 126 -- .../twelvemonkeys/sql/DatabaseReadable.java | 70 - .../com/twelvemonkeys/sql/JDBCHelper.java | 173 -- .../main/java/com/twelvemonkeys/sql/Log.java | 673 ------- .../com/twelvemonkeys/sql/ObjectManager.java | 276 --- .../com/twelvemonkeys/sql/ObjectMapper.java | 663 ------- .../com/twelvemonkeys/sql/ObjectReader.java | 879 --------- .../java/com/twelvemonkeys/sql/SQLUtil.java | 396 ---- .../java/com/twelvemonkeys/sql/package.html | 12 - .../twelvemonkeys/util/AbstractResource.java | 92 - .../com/twelvemonkeys/util/BooleanKey.java | 52 - .../com/twelvemonkeys/util/DebugUtil.java | 1757 ----------------- .../com/twelvemonkeys/util/FileResource.java | 78 - .../java/com/twelvemonkeys/util/FloatKey.java | 52 - .../com/twelvemonkeys/util/IntegerKey.java | 51 - .../twelvemonkeys/util/MappedBeanFactory.java | 456 ----- .../java/com/twelvemonkeys/util/PaintKey.java | 53 - .../com/twelvemonkeys/util/PersistentMap.java | 334 ---- .../twelvemonkeys/util/Rectangle2DKey.java | 53 - .../java/com/twelvemonkeys/util/Resource.java | 80 - .../util/ResourceChangeListener.java | 51 - .../twelvemonkeys/util/ResourceMonitor.java | 207 -- .../com/twelvemonkeys/util/StringKey.java | 52 - .../java/com/twelvemonkeys/util/TypedMap.java | 320 --- .../com/twelvemonkeys/util/URLResource.java | 89 - .../com/twelvemonkeys/util/UUIDFactory.java | 410 ---- .../com/twelvemonkeys/util/XMLProperties.java | 1287 ------------ .../util/regex/REWildcardStringParser.java | 398 ---- .../java/com/twelvemonkeys/xml/XMLReader.java | 55 - .../image/MappedImageFactoryTest.java | 26 - .../io/StringInputStreamTest.java | 126 -- .../io/enc/DeflateEncoderTestCase.java | 18 - .../io/enc/InflateDecoderTestCase.java | 18 - .../twelvemonkeys/lang/DuckTypeTestCase.java | 246 --- .../twelvemonkeys/lang/ExceptionUtilTest.java | 99 - .../util/MappedBeanFactoryTestCase.java | 578 ------ .../twelvemonkeys/util/UUIDFactoryTest.java | 419 ---- .../image/MappedFileBufferTest.java | 137 -- sandbox/sandbox-imageio/pom.xml | 86 - .../Base64DataURLImageInputStreamSpi.java | 65 - .../Base64DataURLImageInputStreamTest.java | 44 - sandbox/sandbox-servlet/pom.xml | 84 - .../servlet/image/TextRenderer.java | 336 ---- .../servlet/jsp/droplet/Droplet.java | 76 - .../servlet/jsp/droplet/JspFragment.java | 42 - .../servlet/jsp/droplet/Oparam.java | 26 - .../servlet/jsp/droplet/Param.java | 41 - .../servlet/jsp/droplet/package-info.java | 9 - .../jsp/droplet/taglib/IncludeTag.java | 214 -- .../jsp/droplet/taglib/NestingHandler.java | 183 -- .../jsp/droplet/taglib/NestingValidator.java | 102 - .../servlet/jsp/droplet/taglib/OparamTag.java | 220 --- .../servlet/jsp/droplet/taglib/ParamTag.java | 129 -- .../jsp/droplet/taglib/ValueOfTEI.java | 47 - .../jsp/droplet/taglib/ValueOfTag.java | 148 -- .../jsp/droplet/taglib/package-info.java | 38 - .../servlet/jsp/package-info.java | 4 - .../servlet/jsp/taglib/BodyReaderTag.java | 39 - .../servlet/jsp/taglib/CSVToTableTag.java | 235 --- .../servlet/jsp/taglib/ExBodyTagSupport.java | 290 --- .../servlet/jsp/taglib/ExTag.java | 163 -- .../servlet/jsp/taglib/ExTagSupport.java | 293 --- .../servlet/jsp/taglib/LastModifiedTEI.java | 20 - .../servlet/jsp/taglib/LastModifiedTag.java | 49 - .../servlet/jsp/taglib/TrimWhiteSpaceTag.java | 87 - .../servlet/jsp/taglib/XMLTransformTag.java | 158 -- .../jsp/taglib/logic/ConditionalTagBase.java | 138 -- .../servlet/jsp/taglib/logic/EqualTag.java | 168 -- .../jsp/taglib/logic/IteratorProviderTEI.java | 40 - .../jsp/taglib/logic/IteratorProviderTag.java | 86 - .../servlet/jsp/taglib/logic/NotEqualTag.java | 168 -- .../servlet/jsp/taglib/package-info.java | 4 - sandbox/sandbox-swing/pom.xml | 153 -- .../swing/filechooser/FileSystemViews.java | 207 -- 109 files changed, 23473 deletions(-) delete mode 100644 sandbox/pom.xml delete mode 100644 sandbox/sandbox-common/pom.xml delete mode 100644 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/AbstractFilter.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/ConvolveTester.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/EasyImage.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/ExtendedImageConsumer.java delete mode 100644 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/GenericWritableRaster.java delete mode 100644 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/InstaCRTFilter.java delete mode 100644 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/InstaLomoFilter.java delete mode 100644 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/InstaSepiaFilter.java delete mode 100644 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/MappedBufferImage.java delete mode 100644 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/MappedFileBuffer.java delete mode 100644 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/MappedImageFactory.java delete mode 100644 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/NoiseFilter.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/SubsampleTester.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/inv_cmap.c delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/io/FileLockingTest.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/io/FileMonitor.java delete mode 100644 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/io/StringInputStream.java delete mode 100644 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/io/enc/DeflateEncoder.java delete mode 100644 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/io/enc/InflateDecoder.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/lang/DuckType.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/lang/ExceptionUtil.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/lang/MathUtil.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/lang/MostUnfortunateException.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/lang/NativeLoader.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/lang/NativeResourceSPI.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/net/AuthenticatorFilter.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/net/BASE64.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/net/HttpURLConnection.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/net/NetUtil.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/net/PasswordAuthenticator.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/net/SimpleAuthenticator.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/DatabaseConnection.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/DatabaseProduct.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/DatabaseReadable.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/JDBCHelper.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/Log.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/ObjectManager.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/ObjectMapper.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/ObjectReader.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/SQLUtil.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/package.html delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/AbstractResource.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/BooleanKey.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/DebugUtil.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/FileResource.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/FloatKey.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/IntegerKey.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/MappedBeanFactory.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/PaintKey.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/PersistentMap.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/Rectangle2DKey.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/Resource.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/ResourceChangeListener.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/ResourceMonitor.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/StringKey.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/TypedMap.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/URLResource.java delete mode 100644 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/UUIDFactory.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/XMLProperties.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/regex/REWildcardStringParser.java delete mode 100755 sandbox/sandbox-common/src/main/java/com/twelvemonkeys/xml/XMLReader.java delete mode 100644 sandbox/sandbox-common/src/test/java/com/twelvemonkeys/image/MappedImageFactoryTest.java delete mode 100644 sandbox/sandbox-common/src/test/java/com/twelvemonkeys/io/StringInputStreamTest.java delete mode 100644 sandbox/sandbox-common/src/test/java/com/twelvemonkeys/io/enc/DeflateEncoderTestCase.java delete mode 100644 sandbox/sandbox-common/src/test/java/com/twelvemonkeys/io/enc/InflateDecoderTestCase.java delete mode 100755 sandbox/sandbox-common/src/test/java/com/twelvemonkeys/lang/DuckTypeTestCase.java delete mode 100644 sandbox/sandbox-common/src/test/java/com/twelvemonkeys/lang/ExceptionUtilTest.java delete mode 100755 sandbox/sandbox-common/src/test/java/com/twelvemonkeys/util/MappedBeanFactoryTestCase.java delete mode 100644 sandbox/sandbox-common/src/test/java/com/twelvemonkeys/util/UUIDFactoryTest.java delete mode 100644 sandbox/sandbox-common/src/test/java/com/twlevemonkeys/image/MappedFileBufferTest.java delete mode 100644 sandbox/sandbox-imageio/pom.xml delete mode 100644 sandbox/sandbox-imageio/src/main/java/com/twelvemonkeys/imageio/stream/Base64DataURLImageInputStreamSpi.java delete mode 100644 sandbox/sandbox-imageio/src/test/java/com/twelvemonkeys/imageio/stream/Base64DataURLImageInputStreamTest.java delete mode 100644 sandbox/sandbox-servlet/pom.xml delete mode 100755 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/image/TextRenderer.java delete mode 100755 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/Droplet.java delete mode 100755 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/JspFragment.java delete mode 100755 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/Oparam.java delete mode 100755 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/Param.java delete mode 100755 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/package-info.java delete mode 100755 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/IncludeTag.java delete mode 100755 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/NestingHandler.java delete mode 100755 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/NestingValidator.java delete mode 100755 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/OparamTag.java delete mode 100755 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/ParamTag.java delete mode 100755 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/ValueOfTEI.java delete mode 100755 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/ValueOfTag.java delete mode 100644 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/package-info.java delete mode 100644 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/package-info.java delete mode 100755 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/BodyReaderTag.java delete mode 100755 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/CSVToTableTag.java delete mode 100755 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/ExBodyTagSupport.java delete mode 100755 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/ExTag.java delete mode 100755 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/ExTagSupport.java delete mode 100755 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/LastModifiedTEI.java delete mode 100755 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/LastModifiedTag.java delete mode 100755 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/TrimWhiteSpaceTag.java delete mode 100755 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/XMLTransformTag.java delete mode 100755 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/logic/ConditionalTagBase.java delete mode 100755 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/logic/EqualTag.java delete mode 100755 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/logic/IteratorProviderTEI.java delete mode 100755 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/logic/IteratorProviderTag.java delete mode 100755 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/logic/NotEqualTag.java delete mode 100644 sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/package-info.java delete mode 100644 sandbox/sandbox-swing/pom.xml delete mode 100644 sandbox/sandbox-swing/src/main/java/com/twelvemonkeys/swing/filechooser/FileSystemViews.java diff --git a/pom.xml b/pom.xml index 67011ce9..4499cbb9 100755 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,6 @@ servlet imageio - contrib bom diff --git a/sandbox/pom.xml b/sandbox/pom.xml deleted file mode 100644 index 5c73b336..00000000 --- a/sandbox/pom.xml +++ /dev/null @@ -1,156 +0,0 @@ - - - 4.0.0 - com.twelvemonkeys.sandbox - sandbox - 3.1-SNAPSHOT - TwelveMonkeys :: Sandbox - pom - - - The TwelveMonkeys Sandbox. Experimental stuff, in progress, not for production use. - - - - com.twelvemonkeys - twelvemonkeys - 3.1-SNAPSHOT - - - - sandbox-common - sandbox-imageio - sandbox-servlet - sandbox-swing - - - - - junit - junit - test - - - - - - - - com.twelvemonkeys.common - common-lang - ${project.version} - compile - - - com.twelvemonkeys.common - common-io - ${project.version} - compile - - - com.twelvemonkeys.common - common-image - ${project.version} - compile - - - com.twelvemonkeys.servlet - servlet - ${project.version} - compile - - - com.twelvemonkeys.swing - swing-core - ${project.version} - compile - - - com.twelvemonkeys.swing - swing-application - ${project.version} - compile - - - com.twelvemonkeys.imageio - imageio-core - ${project.version} - provided - - - com.twelvemonkeys.sandbox - sandbox-common - ${project.version} - compile - - - - com.twelvemonkeys.common - common-io - ${project.version} - test - test-jar - - - com.twelvemonkeys.common - common-lang - ${project.version} - test - test-jar - - - - junit - junit - 4.13.1 - test - - - - - - - - maven-source-plugin - - - - maven-resources-plugin - - UTF-8 - - - - - org.apache.maven.plugins - maven-jar-plugin - 2.4 - - - - ${project.name} - TwelveMonkeys - ${project.version} - http://github.com/haraldk/TwelveMonkeys - - - - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - true - - true - - - - - - diff --git a/sandbox/sandbox-common/pom.xml b/sandbox/sandbox-common/pom.xml deleted file mode 100644 index 31f6b315..00000000 --- a/sandbox/sandbox-common/pom.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - 4.0.0 - - com.twelvemonkeys.sandbox - sandbox - 3.1-SNAPSHOT - - sandbox-common - jar - TwelveMonkeys :: Sandbox :: Common - - The TwelveMonkeys Common Sandbox. Experimental stuff. - - - - - com.twelvemonkeys.common - common-lang - compile - - - - com.twelvemonkeys.common - common-io - compile - - - - com.twelvemonkeys.common - common-image - compile - - - - com.twelvemonkeys.imageio - imageio-core - compile - - - - com.twelvemonkeys.common - common-io - test - test-jar - - - - com.twelvemonkeys.common - common-lang - test - test-jar - - - - diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/AbstractFilter.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/AbstractFilter.java deleted file mode 100644 index 064fae79..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/AbstractFilter.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2012, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.image; - -import javax.imageio.ImageIO; -import javax.swing.*; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.KeyEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.awt.geom.Point2D; -import java.awt.geom.Rectangle2D; -import java.awt.image.BufferedImage; -import java.awt.image.BufferedImageOp; -import java.awt.image.ColorModel; -import java.io.File; -import java.io.IOException; - -/** - * AbstractFilter - * - * @author Harald Kuhr - * @author last modified by $Author: haraldk$ - * @version $Id: AbstractFilter.java,v 1.0 18.06.12 16:55 haraldk Exp$ - */ -public abstract class AbstractFilter implements BufferedImageOp { - public abstract BufferedImage filter(BufferedImage src, BufferedImage dest); - - public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel destCM) { - throw new UnsupportedOperationException("Method createCompatibleDestImage not implemented"); // TODO: Implement - } - - public Rectangle2D getBounds2D(BufferedImage src) { - return new Rectangle2D.Double(0, 0, src.getWidth(), src.getHeight()); - } - - public Point2D getPoint2D(Point2D srcPt, Point2D dstPt) { - if (dstPt == null) { - dstPt = new Point2D.Double(); - } - - dstPt.setLocation(srcPt); - - return dstPt; - } - - public RenderingHints getRenderingHints() { - return null; - } - - protected static void exercise(final String[] args, final BufferedImageOp filter, final Color background) throws IOException { - boolean original = false; - - for (String arg : args) { - if (arg.startsWith("-")) { - if (arg.equals("-o") || arg.equals("--original")) { - original = true; - } - - continue; - } - - final File file = new File(arg); - BufferedImage image = ImageIO.read(file); - - if (image.getWidth() > 640) { - image = new ResampleOp(640, Math.round(image.getHeight() * (640f / image.getWidth())), null).filter(image, null); - } - - if (!original) { - filter.filter(image, image); - } - - final Color bg = original ? Color.BLACK : background; - final BufferedImage img = image; - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - JFrame frame = new JFrame(filter.getClass().getSimpleName().replace("Filter", "") + "Test: " + file.getName()); - frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); - frame.addWindowListener(new WindowAdapter() { - @Override - public void windowClosed(final WindowEvent e) { - Window[] windows = Window.getWindows(); - if (windows == null || windows.length == 0) { - System.exit(0); - } - } - }); - frame.getRootPane().getActionMap().put("window-close", new AbstractAction() { - public void actionPerformed(ActionEvent e) { - Window window = SwingUtilities.getWindowAncestor((Component) e.getSource()); - window.setVisible(false); - window.dispose(); - } - }); - frame.getRootPane().getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_W, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()), "window-close"); - - JLabel label = new JLabel(new BufferedImageIcon(img)); - if (bg != null) { - label.setOpaque(true); - label.setBackground(bg); - } - label.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); - JScrollPane scrollPane = new JScrollPane(label); - scrollPane.setBorder(BorderFactory.createEmptyBorder()); - frame.add(scrollPane); - - frame.pack(); - frame.setLocationByPlatform(true); - frame.setVisible(true); - } - }); - } - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/ConvolveTester.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/ConvolveTester.java deleted file mode 100755 index 437c6449..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/ConvolveTester.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.image; - -import javax.imageio.ImageIO; -import javax.swing.*; -import java.awt.*; -import java.awt.image.BufferedImage; -import java.awt.image.Kernel; -import java.io.File; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; - -/** - * ConvolveTester - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/image/ConvolveTester.java#1 $ - */ -public class ConvolveTester { - - // Initial sample timings (avg, 1000 iterations) - // PNG, type 0: JPEG, type 3: - // ZERO_FILL: 5.4 ms 4.6 ms - // NO_OP: 5.4 ms 4.6 ms - // REFLECT: 42.4 ms 24.9 ms - // WRAP: 86.9 ms 29.5 ms - - final static int ITERATIONS = 1000; - - public static void main(String[] pArgs) throws IOException { - File input = new File(pArgs[0]); - BufferedImage image = ImageIO.read(input); - BufferedImage result = null; - - System.out.println("image: " + image); - - if (pArgs.length > 1) { - float ammount = Float.parseFloat(pArgs[1]); - - int edgeOp = pArgs.length > 2 ? Integer.parseInt(pArgs[2]) : ImageUtil.EDGE_REFLECT; - - long start = System.currentTimeMillis(); - for (int i = 0; i < ITERATIONS; i++) { - result = sharpen(image, ammount, edgeOp); - } - long end = System.currentTimeMillis(); - System.out.println("Time: " + ((end - start) / (double) ITERATIONS) + "ms"); - - showIt(result, "Sharpened " + ammount + " " + input.getName()); - } - else { - showIt(image, "Original " + input.getName()); - } - - } - - public static void showIt(final BufferedImage pImage, final String pTitle) { - try { - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - JFrame frame = new JFrame(pTitle); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - frame.setLocationByPlatform(true); - JPanel pane = new JPanel(new BorderLayout()); - GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration(); - BufferedImageIcon icon = new BufferedImageIcon(ImageUtil.accelerate(pImage, gc)); - JScrollPane scroll = new JScrollPane(new JLabel(icon)); - scroll.setBorder(null); - pane.add(scroll); - frame.setContentPane(pane); - frame.pack(); - frame.setVisible(true); - } - }); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - catch (InvocationTargetException e) { - throw new RuntimeException(e); - } - } - - static BufferedImage sharpen(BufferedImage pOriginal, final float pAmmount, int pEdgeOp) { - if (pAmmount == 0f) { - return pOriginal; - } - - // Create the convolution matrix - float[] data = new float[]{ - 0.0f, -pAmmount, 0.0f, - -pAmmount, 4f * pAmmount + 1f, -pAmmount, - 0.0f, -pAmmount, 0.0f - }; - - // Do the filtering - return ImageUtil.convolve(pOriginal, new Kernel(3, 3, data), pEdgeOp); - - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/EasyImage.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/EasyImage.java deleted file mode 100755 index 71427244..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/EasyImage.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.image; - -import javax.imageio.ImageIO; -import java.awt.*; -import java.awt.image.*; -import java.awt.image.renderable.RenderableImage; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * EasyImage - *

- * - * @author Harald Kuhr - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/image/EasyImage.java#1 $ - */ -public class EasyImage extends BufferedImage { - public EasyImage(InputStream pInput) throws IOException { - this(ImageIO.read(pInput)); - } - - public EasyImage(BufferedImage pImage) { - this(pImage.getColorModel(), pImage.getRaster()); - } - - public EasyImage(RenderableImage pImage) { - this(pImage.createDefaultRendering()); - } - - public EasyImage(RenderedImage pImage) { - this(pImage.getColorModel(), pImage.copyData(pImage.getColorModel().createCompatibleWritableRaster(pImage.getWidth(), pImage.getHeight()))); - } - - public EasyImage(ImageProducer pImage) { - this(new BufferedImageFactory(pImage).getBufferedImage()); - } - - public EasyImage(Image pImage) { - this(new BufferedImageFactory(pImage).getBufferedImage()); - } - - private EasyImage(ColorModel cm, WritableRaster raster) { - super(cm, raster, cm.isAlphaPremultiplied(), null); - } - - public boolean write(String pFormat, OutputStream pOutput) throws IOException { - return ImageIO.write(this, pFormat, pOutput); - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/ExtendedImageConsumer.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/ExtendedImageConsumer.java deleted file mode 100755 index 949d6932..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/ExtendedImageConsumer.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.image; - -import java.awt.image.ImageConsumer; -import java.awt.image.ColorModel; - -/** - * ExtendedImageConsumer - *

- * - * @author Harald Kuhr - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/image/ExtendedImageConsumer.java#1 $ - */ -public interface ExtendedImageConsumer extends ImageConsumer { - /** - * - * @param pX - * @param pY - * @param pWidth - * @param pHeight - * @param pModel - * @param pPixels - * @param pOffset - * @param pScanSize - */ - public void setPixels(int pX, int pY, int pWidth, int pHeight, - ColorModel pModel, - short[] pPixels, int pOffset, int pScanSize); - - // Allow for packed and interleaved models - public void setPixels(int pX, int pY, int pWidth, int pHeight, - ColorModel pModel, - byte[] pPixels, int pOffset, int pScanSize); -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/GenericWritableRaster.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/GenericWritableRaster.java deleted file mode 100644 index e05fc6b2..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/GenericWritableRaster.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2010, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.image; - -import java.awt.*; -import java.awt.image.DataBuffer; -import java.awt.image.SampleModel; -import java.awt.image.WritableRaster; - -/** - * A generic writable raster. - * For use when factory methods from {@link java.awt.image.Raster} can't be used, - * typically because of custom data buffers. - * - * @author Harald Kuhr - * @author last modified by $Author: haraldk$ - * @version $Id: GenericWritableRaster.java,v 1.0 Jun 13, 2010 12:27:45 AM haraldk Exp$ - */ -class GenericWritableRaster extends WritableRaster { - public GenericWritableRaster(final SampleModel model, final DataBuffer buffer, final Point origin) { - super(model, buffer, origin); - } - - @Override - public String toString() { - return String.format( - "%s: %s width = %s height = %s #Bands = %s xOff = %s yOff = %s %s", - getClass().getSimpleName(), - sampleModel, - getWidth(), getHeight(), getNumBands(), - sampleModelTranslateX, sampleModelTranslateY, - dataBuffer - ); - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/InstaCRTFilter.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/InstaCRTFilter.java deleted file mode 100644 index 1929d7fe..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/InstaCRTFilter.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (c) 2012, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.image; - -import java.awt.*; -import java.awt.color.ColorSpace; -import java.awt.image.BufferedImage; -import java.awt.image.ColorConvertOp; -import java.awt.image.RescaleOp; -import java.io.IOException; -import java.util.Random; - -/** - * InstaCRTFilter - * - * @author Harald Kuhr - * @author last modified by $Author: haraldk$ - * @version $Id: InstaCRTFilter.java,v 1.0 15.06.12 13:24 haraldk Exp$ - */ -public class InstaCRTFilter extends AbstractFilter { - - // NOTE: This is a PoC, and not good code... - public BufferedImage filter(BufferedImage src, BufferedImage dest) { - if (dest == null) { - dest = createCompatibleDestImage(src, null); - } - - // Make grayscale - BufferedImage image = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), getRenderingHints()).filter(src, null); - - // Make image faded/too bright - image = new RescaleOp(1.2f, 120f, getRenderingHints()).filter(image, image); - - // Blur - image = ImageUtil.blur(image, 2.5f); - - Graphics2D g = dest.createGraphics(); - try { - g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - g.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY); - g.drawImage(image, 0, 0, null); - - // Rotate it slightly for a more analogue feeling - double angle = .0055; - g.rotate(angle); - - // Apply fake green-ish h-sync line at random position - Random random = new Random(); - int lineStart = random.nextInt(image.getHeight() - 80); - int lineHeight = random.nextInt(10) + 20; - - g.setComposite(AlphaComposite.SrcOver.derive(.3f)); - g.setPaint(new LinearGradientPaint( - 0, lineStart, 0, lineStart + lineHeight, - new float[] {0, .3f, .9f, 1}, - new Color[] {new Color(0, true), new Color(0x90AF66), new Color(0x99606F33, true), new Color(0, true)} - )); - g.fillRect(0, lineStart, image.getWidth(), lineHeight); - - // Apply fake large dot-pitch (black lines w/transparency) - g.setComposite(AlphaComposite.SrcOver.derive(.55f)); - g.setColor(Color.BLACK); - - for (int y = 0; y < image.getHeight(); y += 3) { - g.setStroke(new BasicStroke(random.nextFloat() / 3 + .8f)); - g.drawLine(0, y, image.getWidth(), y); - } - - // Vignette/border - g.setComposite(AlphaComposite.SrcOver.derive(.75f)); - int focus = Math.min(image.getWidth() / 8, image.getHeight() / 8); - g.setPaint(new RadialGradientPaint( - new Point(image.getWidth() / 2, image.getHeight() / 2), - Math.max(image.getWidth(), image.getHeight()) / 1.6f, - new Point(focus, focus), - new float[] {0, .3f, .9f, 1f}, - new Color[] {new Color(0x99FFFFFF, true), new Color(0x00FFFFFF, true), new Color(0x0, true), Color.BLACK}, - MultipleGradientPaint.CycleMethod.NO_CYCLE - )); - g.fillRect(-2, -2, image.getWidth() + 4, image.getHeight() + 4); - - g.rotate(-angle); - - g.setComposite(AlphaComposite.SrcOver.derive(.35f)); - g.setPaint(new RadialGradientPaint( - new Point(image.getWidth() / 2, image.getHeight() / 2), - Math.max(image.getWidth(), image.getHeight()) / 1.65f, - new Point(image.getWidth() / 2, image.getHeight() / 2), - new float[] {0, .85f, 1f}, - new Color[] {new Color(0x0, true), new Color(0x0, true), Color.BLACK}, - MultipleGradientPaint.CycleMethod.NO_CYCLE - )); - g.fillRect(0, 0, image.getWidth(), image.getHeight()); - - // Highlight - g.setComposite(AlphaComposite.SrcOver.derive(.55f)); - g.setPaint(new RadialGradientPaint( - new Point(image.getWidth(), image.getHeight()), - Math.max(image.getWidth(), image.getHeight()) * 1.1f, - new Point(image.getWidth() / 2, image.getHeight() / 2), - new float[] {0, .75f, 1f}, - new Color[] {new Color(0x00FFFFFF, true), new Color(0x00FFFFFF, true), Color.WHITE}, - MultipleGradientPaint.CycleMethod.NO_CYCLE - )); - g.fillRect(0, 0, image.getWidth(), image.getHeight()); - } - finally { - g.dispose(); - } - - // Round corners - BufferedImage foo = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB); - Graphics2D graphics = foo.createGraphics(); - try { - graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - graphics.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY); - graphics.setColor(Color.WHITE); - double angle = -0.04; - g.rotate(angle); - graphics.fillRoundRect(1, 1, image.getWidth() - 2, image.getHeight() - 2, 20, 20); - } - finally { - graphics.dispose(); - } - - foo = ImageUtil.blur(foo, 4.5f); - - // Compose image into rounded corners - graphics = foo.createGraphics(); - try { - graphics.setComposite(AlphaComposite.SrcIn); - graphics.drawImage(dest, 0, 0, null); - } - finally { - graphics.dispose(); - } - - // Draw it all back to dest - g = dest.createGraphics(); - try { - g.setComposite(AlphaComposite.SrcOver); - g.setColor(Color.BLACK); - g.fillRect(0, 0, image.getWidth(), image.getHeight()); - g.drawImage(foo, 0, 0, null); - } - finally { - g.dispose(); - } - - return dest; - } - - public static void main(String[] args) throws IOException { - exercise(args, new InstaCRTFilter(), Color.BLACK); - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/InstaLomoFilter.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/InstaLomoFilter.java deleted file mode 100644 index 6d277717..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/InstaLomoFilter.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (c) 2012, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.image; - -import java.awt.*; -import java.awt.image.BufferedImage; -import java.awt.image.RescaleOp; -import java.io.IOException; -import java.util.Random; - -/** - * InstaLomoFilter - * - * @author Harald Kuhr - * @author last modified by $Author: haraldk$ - * @version $Id: InstaLomoFilter.java,v 1.0 15.06.12 13:24 haraldk Exp$ - */ -public class InstaLomoFilter extends AbstractFilter { - final private Random random = new Random(); - - // NOTE: This is a PoC, and not good code... - public BufferedImage filter(BufferedImage src, BufferedImage dest) { - if (dest == null) { - dest = createCompatibleDestImage(src, null); - } - - // Make image faded/washed out/red-ish - // DARK WARM - float[] scales = new float[] { 2.2f, 2.0f, 1.55f}; - float[] offsets = new float[] {-20.0f, -90.0f, -110.0f}; - - // BRIGHT NATURAL -// float[] scales = new float[] { 1.1f, .9f, .7f}; -// float[] offsets = new float[] {20, 30, 80}; - - // Faded, old-style -// float[] scales = new float[] { 1.1f, .7f, .3f}; -// float[] offsets = new float[] {20, 30, 80}; - -// float[] scales = new float[] { 1.2f, .4f, .4f}; -// float[] offsets = new float[] {0, 120, 120}; - - // BRIGHT WARM -// float[] scales = new float[] {1.1f, .8f, 1.6f}; -// float[] offsets = new float[] {60, 70, -80}; - BufferedImage image = new RescaleOp(scales, offsets, getRenderingHints()).filter(src, null); - - // Blur - image = ImageUtil.blur(image, 2.5f); - - Graphics2D g = dest.createGraphics(); - try { - g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - g.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY); - g.drawImage(image, 0, 0, null); - - // Rotate it slightly for a more analogue feeling - double angle = .0055; - g.rotate(angle); - - // Scratches - g.setComposite(AlphaComposite.SrcOver.derive(.025f)); - for (int i = 0; i < 100; i++) { - g.setColor(random.nextBoolean() ? Color.WHITE : Color.BLACK); - g.setStroke(new BasicStroke(random.nextFloat() * 2f)); - int x = random.nextInt(image.getWidth()); - - int off = random.nextInt(100); - for (int j = random.nextInt(3); j > 0; j--) { - g.drawLine(x + j, 0, x + off - 50 + j, image.getHeight()); - } - } - - // Vignette/border - g.setComposite(AlphaComposite.SrcOver.derive(.75f)); - int focus = Math.min(image.getWidth() / 8, image.getHeight() / 8); - g.setPaint(new RadialGradientPaint( - new Point(image.getWidth() / 2, image.getHeight() / 2), - Math.max(image.getWidth(), image.getHeight()) / 1.6f, - new Point(focus, focus), - new float[] {0, .3f, .9f, 1f}, - new Color[] {new Color(0x99FFFFFF, true), new Color(0x00FFFFFF, true), new Color(0x0, true), Color.BLACK}, - MultipleGradientPaint.CycleMethod.NO_CYCLE - )); - g.fillRect(-2, -2, image.getWidth() + 4, image.getHeight() + 4); - - g.rotate(-angle); - - g.setComposite(AlphaComposite.SrcOver.derive(.35f)); - g.setPaint(new RadialGradientPaint( - new Point(image.getWidth() / 2, image.getHeight() / 2), - Math.max(image.getWidth(), image.getHeight()) / 1.65f, - new Point(image.getWidth() / 2, image.getHeight() / 2), - new float[] {0, .85f, 1f}, - new Color[] {new Color(0x0, true), new Color(0x0, true), Color.BLACK}, - MultipleGradientPaint.CycleMethod.NO_CYCLE - )); - g.fillRect(0, 0, image.getWidth(), image.getHeight()); - - // Highlight - g.setComposite(AlphaComposite.SrcOver.derive(.35f)); - g.setPaint(new RadialGradientPaint( - new Point(image.getWidth(), image.getHeight()), - Math.max(image.getWidth(), image.getHeight()) * 1.1f, - new Point(image.getWidth() / 2, image.getHeight() / 2), - new float[] {0, .75f, 1f}, - new Color[] {new Color(0x00FFFFFF, true), new Color(0x00FFFFFF, true), Color.PINK}, - MultipleGradientPaint.CycleMethod.NO_CYCLE - )); - g.fillRect(0, 0, image.getWidth(), image.getHeight()); - } - finally { - g.dispose(); - } - - // Noise - NoiseFilter noise = new NoiseFilter(); - noise.setAmount(10); - noise.setDensity(2); - dest = noise.filter(dest, dest); - - // Round corners - BufferedImage foo = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB); - Graphics2D graphics = foo.createGraphics(); - try { - graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - graphics.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY); - graphics.setColor(Color.WHITE); - double angle = (random.nextDouble() * .01) - .005; - graphics.rotate(angle); - graphics.fillRoundRect(4, 4, image.getWidth() - 8, image.getHeight() - 8, 20, 20); - } - finally { - graphics.dispose(); - } - - noise.setAmount(20); - noise.setDensity(1); - noise.setMonochrome(true); - foo = noise.filter(foo, foo); - - foo = ImageUtil.blur(foo, 4.5f); - - // Compose image into rounded corners - graphics = foo.createGraphics(); - try { - graphics.setComposite(AlphaComposite.SrcIn); - graphics.drawImage(dest, 0, 0, null); - } - finally { - graphics.dispose(); - } - - // Draw it all back to dest - g = dest.createGraphics(); - try { - if (dest.getTransparency() != Transparency.OPAQUE) { - g.setComposite(AlphaComposite.Clear); - } - g.setColor(Color.WHITE); - g.fillRect(0, 0, image.getWidth(), image.getHeight()); - g.setComposite(AlphaComposite.SrcOver); - g.drawImage(foo, 0, 0, null); - } - finally { - g.dispose(); - } - - return dest; - } - - public static void main(String[] args) throws IOException { - exercise(args, new InstaLomoFilter(), Color.WHITE); - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/InstaSepiaFilter.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/InstaSepiaFilter.java deleted file mode 100644 index b82c6b9c..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/InstaSepiaFilter.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2012, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.image; - -import java.awt.*; -import java.awt.color.ColorSpace; -import java.awt.image.*; -import java.io.IOException; -import java.util.Random; - -/** - * InstaLomoFilter - * - * @author Harald Kuhr - * @author last modified by $Author: haraldk$ - * @version $Id: InstaLomoFilter.java,v 1.0 15.06.12 13:24 haraldk Exp$ - */ -public class InstaSepiaFilter extends AbstractFilter { - final private Random random = new Random(); - - // NOTE: This is a PoC, and not good code... - @Override - public BufferedImage filter(BufferedImage src, BufferedImage dest) { - if (dest == null) { - dest = createCompatibleDestImage(src, null); - } - - BufferedImage image = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), getRenderingHints()).filter(src, dest); - - Graphics2D g2d = dest.createGraphics(); - try { - g2d.drawImage(image, 0, 0, null); - } - finally { - g2d.dispose(); - } - - // Blur - image = ImageUtil.blur(image, 2.5f); - - Graphics2D g = dest.createGraphics(); - try { - g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - g.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY); - g.drawImage(image, 0, 0, null); - - // Rotate it slightly for a more analogue feeling - double angle = -.0055; - g.rotate(angle); - - // Vignette/border - g.setComposite(AlphaComposite.SrcOver.derive(.35f)); - g.setPaint(new RadialGradientPaint( - new Point(image.getWidth() / 2, image.getHeight() / 2), - Math.max(image.getWidth(), image.getHeight()) / 1.65f, - new Point(image.getWidth() / 2, image.getHeight() / 2), - new float[] {0, .85f, 1f}, - new Color[] {new Color(0x0, true), new Color(0x0, true), Color.BLACK}, - MultipleGradientPaint.CycleMethod.NO_CYCLE - )); - g.fillRect(0, 0, image.getWidth(), image.getHeight()); - - } - finally { - g.dispose(); - } - - // Round corners - BufferedImage foo = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB); - Graphics2D graphics = foo.createGraphics(); - try { - graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - graphics.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY); - graphics.setColor(Color.WHITE); - double angle = (random.nextDouble() * .01) - .005; - graphics.rotate(angle); - graphics.fillRoundRect(4, 4, image.getWidth() - 8, image.getHeight() - 8, 20, 20); - } - finally { - graphics.dispose(); - } - - // Noise - NoiseFilter noise = new NoiseFilter(); - noise.setAmount(20); - noise.setDensity(1); - noise.setMonochrome(true); - foo = noise.filter(foo, foo); - - foo = ImageUtil.blur(foo, 4.5f); - - // Compose image into rounded corners - graphics = foo.createGraphics(); - try { - graphics.setComposite(AlphaComposite.SrcIn); - graphics.drawImage(dest, 0, 0, null); - } - finally { - graphics.dispose(); - } - - float[] scales = new float[] {1, 1, 1, 1}; - float[] offsets = new float[] {80, 40, 0, 0}; - foo = new RescaleOp(scales, offsets, getRenderingHints()).filter(foo, foo); - - // Draw it all back to dest - g = dest.createGraphics(); - try { - g.setComposite(AlphaComposite.SrcOver); - g.setColor(Color.WHITE); - g.fillRect(0, 0, image.getWidth(), image.getHeight()); - g.drawImage(foo, 0, 0, null); - } - finally { - g.dispose(); - } - - return dest; - } - - public static void main(String[] args) throws IOException { - exercise(args, new InstaSepiaFilter(), null); - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/MappedBufferImage.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/MappedBufferImage.java deleted file mode 100644 index 2954364c..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/MappedBufferImage.java +++ /dev/null @@ -1,1019 +0,0 @@ -/* - * Copyright (c) 2010, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.image; - -import com.twelvemonkeys.imageio.util.ProgressListenerBase; -import com.twelvemonkeys.lang.StringUtil; -import com.twelvemonkeys.util.LRUHashMap; - -import javax.imageio.ImageIO; -import javax.imageio.ImageReadParam; -import javax.imageio.ImageReader; -import javax.imageio.ImageTypeSpecifier; -import javax.imageio.stream.ImageInputStream; -import javax.swing.*; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.KeyEvent; -import java.awt.image.BufferedImage; -import java.awt.image.DataBuffer; -import java.io.File; -import java.io.IOException; -import java.lang.ref.Reference; -import java.lang.ref.SoftReference; -import java.util.*; -import java.util.List; -import java.util.concurrent.*; - -/** - * MappedBufferImage - * - * @author Harald Kuhr - * @author last modified by $Author: haraldk$ - * @version $Id: MappedBufferImage.java,v 1.0 Jun 13, 2010 7:33:19 PM haraldk Exp$ - */ -public class MappedBufferImage { - private static int threads = Runtime.getRuntime().availableProcessors(); - private static ExecutorService executorService = Executors.newFixedThreadPool(threads * 4); - private static ExecutorService executorService2 = Executors.newFixedThreadPool(2); - - public static void main(String[] args) throws IOException { - int argIndex = 0; - File file = args.length > 0 ? new File(args[argIndex]) : null; - - int w; - int h; - BufferedImage image; - - if (file != null && file.exists()) { - argIndex++; - - // Load image using ImageIO - ImageInputStream input = ImageIO.createImageInputStream(file); - Iterator readers = ImageIO.getImageReaders(input); - - if (!readers.hasNext()) { - System.err.println("No image reader found for input: " + file.getAbsolutePath()); - System.exit(0); - return; - } - - ImageReader reader = readers.next(); - try { - reader.setInput(input); - - Iterator types = reader.getImageTypes(0); - ImageTypeSpecifier type = types.next(); - - // TODO: Negotiate best layout according to the GraphicsConfiguration. - - int sub = 1; - w = reader.getWidth(0) / sub; - h = reader.getHeight(0) / sub; - - // GraphicsConfiguration configuration = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration(); - // ColorModel cm2 = configuration.getColorModel(cm.getTransparency()); - - // image = MappedImageFactory.createCompatibleMappedImage(w, h, cm2); - // image = MappedImageFactory.createCompatibleMappedImage(w, h, cm); - // image = MappedImageFactory.createCompatibleMappedImage(w, h, BufferedImage.TYPE_4BYTE_ABGR); - // image = MappedImageFactory.createCompatibleMappedImage(w, h, BufferedImage.TYPE_INT_BGR); -// image = MappedImageFactory.createCompatibleMappedImage(w, h, type); -// if (w > 1024 || h > 1024) { - image = MappedImageFactory.createCompatibleMappedImage(w, h, type); -// } -// else { -// image = type.createBufferedImage(w, h); -// } - - System.out.println("image = " + image); - - // TODO: Display image while reading - - ImageReadParam param = reader.getDefaultReadParam(); - param.setDestination(image); - param.setSourceSubsampling(sub, sub, 0, 0); - - reader.addIIOReadProgressListener(new ConsoleProgressListener()); - reader.read(0, param); - } - finally { - reader.dispose(); - } - } - else { - w = args.length > argIndex && StringUtil.isNumber(args[argIndex]) ? Integer.parseInt(args[argIndex++]) : 6000; - h = args.length > argIndex && StringUtil.isNumber(args[argIndex]) ? Integer.parseInt(args[argIndex++]) : w * 2 / 3; - - GraphicsConfiguration configuration = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration(); - image = MappedImageFactory.createCompatibleMappedImage(w, h, configuration, Transparency.TRANSLUCENT); -// image = MappedImageFactory.createCompatibleMappedImage(w, h, configuration, Transparency.OPAQUE); -// image = MappedImageFactory.createCompatibleMappedImage(w, h, BufferedImage.TYPE_4BYTE_ABGR); - - System.out.println("image = " + image); - - DataBuffer buffer = image.getRaster().getDataBuffer(); - final boolean alpha = image.getColorModel().hasAlpha(); - - // Mix in some nice colors - createBackground(w, h, buffer, alpha); - - // Add some random dots (get out the coffee) - paintDots(w, h, image); - } - - // Resample down to some fixed size - if (args.length > argIndex && "-scale".equals(args[argIndex++])) { - image = resampleImage(image, 800); - } - - int bytesPerPixel = image.getColorModel().getPixelSize() / 8; // Calculate first to avoid overflow - String size = toHumanReadableSize(w * h * bytesPerPixel); - showIt(w, h, image, size); - } - - private static void showIt(final int w, final int h, BufferedImage image, final String size) { - JFrame frame = new JFrame(String.format("Test [%s x %s] (%s)", w, h, size)) { - @Override - public Dimension getPreferredSize() { - // TODO: This looks like a useful util method... - DisplayMode displayMode = getGraphicsConfiguration().getDevice().getDisplayMode(); - Dimension size = super.getPreferredSize(); - - size.width = Math.min(size.width, displayMode.getWidth()); - size.height = Math.min(size.height, displayMode.getHeight()); - - return size; - } - }; - frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - JScrollPane scroll = new JScrollPane(new ImageComponent(image)); - scroll.setBorder(BorderFactory.createEmptyBorder()); - frame.add(scroll); - frame.pack(); - frame.setLocationRelativeTo(null); - frame.setVisible(true); - } - - private static BufferedImage resampleImage(final BufferedImage image, final int width) { - long start = System.currentTimeMillis(); - - float aspect = image.getHeight() / (float) image.getWidth(); - int height = Math.round(width * aspect); - - // NOTE: The createCompatibleDestImage takes the byte order/layout into account, unlike the cm.createCompatibleWritableRaster - final BufferedImage output = new ResampleOp(width, height).createCompatibleDestImage(image, null); - - final int steps = threads * height / 100; - final int inStep = (int) Math.ceil(image.getHeight() / (double) steps); - final int outStep = (int) Math.ceil(height / (double) steps); - - final CountDownLatch latch = new CountDownLatch(steps); - - // System.out.println("Starting image scale on single thread, waiting for execution to complete..."); -// BufferedImage output = new ResampleOp(width, height, ResampleOp.FILTER_LANCZOS).filter(image, null); - System.out.printf("Started image scale on %d threads, waiting for execution to complete...\n", threads); - - System.out.print("["); - final int dotsPerStep = 78 / steps; - for (int j = 0; j < 78 - (steps * dotsPerStep); j++) { - System.out.print("."); - } - - // Resample image in slices - for (int i = 0; i < steps; i++) { - final int inY = i * inStep; - final int outY = i * outStep; - final int inHeight = Math.min(inStep, image.getHeight() - inY); - final int outHeight = Math.min(outStep, output.getHeight() - outY); - executorService.submit(new Runnable() { - public void run() { - try { - BufferedImage in = image.getSubimage(0, inY, image.getWidth(), inHeight); - BufferedImage out = output.getSubimage(0, outY, width, outHeight); - new ResampleOp(width, outHeight, ResampleOp.FILTER_TRIANGLE).filter(in, out); -// new ResampleOp(width, outHeight, ResampleOp.FILTER_LANCZOS).filter(in, out); - - for (int j = 0; j < dotsPerStep; j++) { - System.out.print("."); - } - } - catch (RuntimeException e) { - e.printStackTrace(); - throw e; - } - finally { - latch.countDown(); - } - } - }); - } - - Boolean done = null; - try { - done = latch.await(5L, TimeUnit.MINUTES); - } - catch (InterruptedException ignore) { - } - System.out.println("]"); - - System.out.printf("%s scaling image in %d ms\n", (done == null ? "Interrupted" : !done ? "Timed out" : "Done"), System.currentTimeMillis() - start); - System.out.println("image = " + output); - - return output; - } - - private static void paintDots(int width, int height, final BufferedImage image) { - long start = System.currentTimeMillis(); - - int s = 300; - int ws = width / s; - int hs = height / s; - - Color[] colors = new Color[] { - Color.WHITE, Color.ORANGE, Color.BLUE, Color.MAGENTA, Color.BLACK, Color.RED, Color.CYAN, - Color.GRAY, Color.GREEN, Color.YELLOW, Color.PINK, Color.LIGHT_GRAY, Color.DARK_GRAY - }; - - CountDownLatch latch = new CountDownLatch(threads); - int step = (int) Math.ceil(hs / (double) threads); - Random r = new Random(); - - for (int i = 0; i < threads; i++) { - executorService.submit(new PaintDotsTask(image, s, ws, colors, r, i * step, i * step + step, latch)); - } - - System.err.printf("Started painting in %d threads, waiting for execution to complete...%n", threads); - - Boolean done = null; - try { - done = latch.await(3L, TimeUnit.MINUTES); - } - catch (InterruptedException ignore) { - } - - System.out.printf("%s painting %d dots in %d ms%n", (done == null ? "Interrupted" : !done ? "Timed out" : "Done"), Math.max(0, hs - 1) * Math.max(0, ws - 1), System.currentTimeMillis() - start); - } - - private static void paintDots0(BufferedImage image, int s, int ws, Color[] colors, Random r, final int first, final int last) { - for (int y = first; y < last; y++) { - for (int x = 0; x < ws - 1; x++) { - BufferedImage tile = image.getSubimage(x * s, y * s, 2 * s, 2 * s); - Graphics2D g; - try { - g = tile.createGraphics(); - } - catch (OutOfMemoryError e) { - System.gc(); - System.err.println("Out of memory: " + e.getMessage()); - g = tile.createGraphics(); // If this fails, give up - } - - try { - g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - g.setComposite(AlphaComposite.SrcOver.derive(r.nextFloat())); - g.setColor(colors[r.nextInt(colors.length)]); - int o = r.nextInt(s) + s / 10; - int c = (2 * s - o) / 2; - g.fillOval(c, c, o, o); - } - finally { - g.dispose(); - } - } - } - } - - private static void createBackground(int w, int h, DataBuffer buffer, boolean alpha) { - long start = System.currentTimeMillis(); - - int step = (int) Math.ceil(h / (double) threads); - - CountDownLatch latch = new CountDownLatch(threads); - for (int i = 0; i < threads; i++) { - executorService.submit(new PaintBackgroundTask(w, h, buffer, alpha, i * step, i * step + step, latch)); - } - System.err.printf("Started painting in %d threads, waiting for execution to complete...%n", threads); - - Boolean done = null; - try { - done = latch.await(3L, TimeUnit.MINUTES); - } - catch (InterruptedException ignore) { - } - - System.out.printf("%s creating background in %d ms%n", (done == null ? "Interrupted" : !done ? "Timed out" : "Done"), System.currentTimeMillis() - start); - } - - private static void paintBackground0(int w, int h, DataBuffer buffer, boolean alpha, final int first, final int last) { - for (int y = first; y < last; y++) { - for (int x = 0; x < w; x++) { - int r = (int) ((x * y * 255.0) / (h * w)); - int g = (int) (((w - x) * y * 255.0) / (h * w)); - int b = (int) ((x * (h - y) * 255.0) / (h * w)); - int a = alpha ? (int) (((w - x) * (h - y) * 255.0) / (h * w)) : 0; - - switch (buffer.getDataType()) { - case DataBuffer.TYPE_BYTE: - int off = (y * w + x) * (alpha ? 4 : 3); - if (alpha) { - buffer.setElem(off++, 255 - a); - buffer.setElem(off++, b); - buffer.setElem(off++, g); - buffer.setElem(off, r); - } - else { - // TODO: Why the RGB / ABGR byte order inconsistency?? - buffer.setElem(off++, r); - buffer.setElem(off++, g); - buffer.setElem(off, b); - } - break; - case DataBuffer.TYPE_INT: - buffer.setElem(y * w + x, (255 - a) << 24 | r << 16 | g << 8 | b); - break; - default: - System.err.println("Transfer type not supported: " + buffer.getDataType()); - } - } - } - } - - private static String toHumanReadableSize(long size) { - return String.format("%,d MB", (long) (size / (double) (1024L << 10))); - } - - /** - * A fairly optimized component for displaying a BufferedImage - */ - private static class ImageComponent extends JComponent implements Scrollable { - private final BufferedImage image; - private Paint texture; - private double zoom = 1; - - public ImageComponent(final BufferedImage image) { - setOpaque(true); // Very important when sub classing JComponent... - setDoubleBuffered(true); - - this.image = image; - } - - @Override - public void addNotify() { - super.addNotify(); - - texture = createTexture(); - - Rectangle bounds = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds(); - zoom = Math.min(1.0, Math.min(bounds.getWidth() / (double) image.getWidth(), bounds.getHeight() / (double) image.getHeight())); - - // TODO: Take scroll pane into account when zooming (center around center point) - AbstractAction zoomIn = new AbstractAction() { - public void actionPerformed(ActionEvent e) { - System.err.println("ZOOM IN"); - setZoom(zoom * 2); - } - }; - - addAction(KeyStroke.getKeyStroke(KeyEvent.VK_PLUS, getToolkit().getMenuShortcutKeyMask()), zoomIn); - addAction(KeyStroke.getKeyStroke(KeyEvent.VK_ADD, getToolkit().getMenuShortcutKeyMask()), zoomIn); - addAction(KeyStroke.getKeyStroke(Character.valueOf('+'), 0), zoomIn); - addAction(KeyStroke.getKeyStroke(Character.valueOf('+'), getToolkit().getMenuShortcutKeyMask()), zoomIn); - AbstractAction zoomOut = new AbstractAction() { - public void actionPerformed(ActionEvent e) { - System.err.println("ZOOM OUT"); - setZoom(zoom / 2); - } - }; - addAction(KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, getToolkit().getMenuShortcutKeyMask()), zoomOut); - addAction(KeyStroke.getKeyStroke(KeyEvent.VK_SUBTRACT, getToolkit().getMenuShortcutKeyMask()), zoomOut); - addAction(KeyStroke.getKeyStroke(Character.valueOf('-'), 0), zoomOut); - addAction(KeyStroke.getKeyStroke(Character.valueOf('-'), getToolkit().getMenuShortcutKeyMask()), zoomOut); - AbstractAction zoomFit = new AbstractAction() { - public void actionPerformed(ActionEvent e) { - System.err.println("ZOOM FIT"); -// Rectangle bounds = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds(); - Rectangle bounds = getVisibleRect(); - setZoom(Math.min(1.0, Math.min(bounds.getWidth() / (double) image.getWidth(), bounds.getHeight() / (double) image.getHeight()))); - } - }; - addAction(KeyStroke.getKeyStroke(KeyEvent.VK_EQUALS, getToolkit().getMenuShortcutKeyMask()), zoomFit); - addAction(KeyStroke.getKeyStroke(KeyEvent.VK_9, getToolkit().getMenuShortcutKeyMask()), zoomFit); - addAction(KeyStroke.getKeyStroke(KeyEvent.VK_0, getToolkit().getMenuShortcutKeyMask()), new AbstractAction() { - public void actionPerformed(ActionEvent e) { - System.err.println("ZOOM ACTUAL"); - setZoom(1); - } - }); - } - - private void setZoom(final double newZoom) { - if (newZoom != zoom) { - zoom = newZoom; - // TODO: Add PCL support for zoom and discard tiles cache based on property change - tiles = createTileCache(); - revalidate(); - repaint(); - } - } - - private Map createTileCache() { - return Collections.synchronizedMap(new SizedLRUMap(16 * 1024 * 1024)); - } - - private void addAction(final KeyStroke keyStroke, final AbstractAction action) { - UUID key = UUID.randomUUID(); - getInputMap(WHEN_IN_FOCUSED_WINDOW).put(keyStroke, key); - getActionMap().put(key, action); - } - - private Paint createTexture() { - BufferedImage pattern = getGraphicsConfiguration().createCompatibleImage(20, 20); - Graphics2D g = pattern.createGraphics(); - - try { - g.setColor(Color.LIGHT_GRAY); - g.fillRect(0, 0, pattern.getWidth(), pattern.getHeight()); - g.setColor(Color.GRAY); - g.fillRect(0, 0, pattern.getWidth() / 2, pattern.getHeight() / 2); - g.fillRect(pattern.getWidth() / 2, pattern.getHeight() / 2, pattern.getWidth() / 2, pattern.getHeight() / 2); - } - finally { - g.dispose(); - } - - return new TexturePaint(pattern, new Rectangle(pattern.getWidth(), pattern.getHeight())); - } - - @Override - protected void paintComponent(Graphics g) { - // TODO: Java 7 kills the performance from our custom painting... :-( - - // TODO: Figure out why mouse wheel/track pad scroll repaints entire component, - // unlike using the scroll bars of the JScrollPane. - // Consider creating a custom mouse wheel listener as a workaround. - - // TODO: Cache visible rect content in buffered/volatile image (s) + visible rect (+ zoom) to speed up repaints - // - Blit the cahced image (possibly translated) (onto itself?) - // - Paint only the necessary parts outside the cached image - // - Async rendering into cached image - - // We want to paint only the visible part of the image - Rectangle visible = getVisibleRect(); - Rectangle clip = g.getClipBounds(); - Rectangle rect = clip == null ? visible : visible.intersection(clip); - - Graphics2D g2 = (Graphics2D) g; - g2.setPaint(texture); - g2.fillRect(rect.x, rect.y, rect.width, rect.height); - - /* - // Center image (might not be the best way to cooperate with the scroll pane) - Rectangle imageSize = new Rectangle((int) Math.round(image.getWidth() * zoom), (int) Math.round(image.getHeight() * zoom)); - if (imageSize.width < getWidth()) { - g2.translate((getWidth() - imageSize.width) / 2, 0); - } - if (imageSize.height < getHeight()) { - g2.translate(0, (getHeight() - imageSize.height) / 2); - } - */ - - // Zoom - if (zoom != 1) { - // NOTE: This helps mostly when scaling up, or scaling down less than 50% - g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); - - rect = new Rectangle( - (int) Math.round(rect.x / zoom), (int) Math.round(rect.y / zoom), - (int) Math.round(rect.width / zoom), (int) Math.round(rect.height / zoom) - ); - - rect = rect.intersection(new Rectangle(image.getWidth(), image.getHeight())); - } - - long start = System.currentTimeMillis(); - repaintImage(rect, g2); - System.err.println("repaint: " + (System.currentTimeMillis() - start) + " ms"); - } - - static class Tile { - private final int size; - - private final int x; - private final int y; - - private final Reference data; - private final BufferedImage hardRef; - - Tile(int x, int y, BufferedImage data) { - this.x = x; - this.y = y; - this.data = new SoftReference(data); - - hardRef = data; - - size = 16 + data.getWidth() * data.getHeight() * data.getRaster().getNumDataElements() * sizeOf(data.getRaster().getTransferType()); - } - - private static int sizeOf(final int transferType) { - switch (transferType) { - case DataBuffer.TYPE_INT: - return 4; - case DataBuffer.TYPE_SHORT: - return 2; - case DataBuffer.TYPE_BYTE: - return 1; - default: - throw new IllegalArgumentException("Unsupported transfer type: " + transferType); - } - } - - public boolean drawTo(Graphics2D g) { - BufferedImage img = data.get(); - - if (img != null) { - g.drawImage(img, x, y, null); - return true; - } - - return false; - } - - public int getX() { - return x; - } - - public int getY() { - return y; - } - - public int getWidth() { - BufferedImage img = data.get(); - return img != null ? img.getWidth() : -1; - } - - public int getHeight() { - BufferedImage img = data.get(); - return img != null ? img.getHeight() : -1; - } - - public Rectangle getRect() { - BufferedImage img = data.get(); - return img != null ? new Rectangle(x, y, img.getWidth(), img.getHeight()) : null; - } - - public Point getLocation() { - return new Point(x, y); - } - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } - - if (other == null || getClass() != other.getClass()) { - return false; - } - - Tile tile = (Tile) other; - - return x == tile.x && y == tile.y; - } - - @Override - public int hashCode() { - return 997 * x + y; - } - - @Override - public String toString() { - return String.format("Tile[%d, %d, %d, %d]", x, y, getWidth(), getHeight()); - } - - public int size() { - return size; - } - } - - // TODO: Consider a fixed size (mem) LRUCache instead - // TODO: Better yet, re-use tiles - Map tiles = createTileCache(); - - private void repaintImage(final Rectangle rect, final Graphics2D g2) { -// System.err.println("rect: " + rect); -// System.err.println("tiles: " + tiles.size()); - // TODO: Fix rounding errors - // FIx repaint bugs - - try { - // Paint tiles of the image, to preserve memory - final int tileSize = 200; - - // Calculate relative to image(0,0), rather than rect(x, y) - int xOff = rect.x % tileSize; - int yOff = rect.y % tileSize; - - rect.x -= xOff; - rect.y -= yOff; - rect.width += xOff; - rect.height += yOff; - - int tilesW = 1 + rect.width / tileSize; - int tilesH = 1 + rect.height / tileSize; - - for (int yTile = 0; yTile <= tilesH; yTile++) { - for (int xTile = 0; xTile <= tilesW; xTile++) { - // Image (source) coordinates - int x = rect.x + xTile * tileSize; - int y = rect.y + yTile * tileSize; - - int w = xTile == tilesW ? Math.min(tileSize, rect.x + rect.width - x) : tileSize; - int h = yTile == tilesH ? Math.min(tileSize, rect.y + rect.height - y) : tileSize; - - if (w == 0 || h == 0) { - continue; - } - -// System.err.printf("%04d, %04d, %04d, %04d%n", x, y, w, h); - - // - Get tile from cache - // - If non-null, paint - // - If null, request data for later use, with callback, and return - // TODO: Could we use ImageProducer/ImageConsumer/ImageObserver interface?? - - // Destination (display) coordinates - int dstX = (int) Math.floor(x * zoom); - int dstY = (int) Math.floor(y * zoom); - int dstW = (int) Math.ceil(w * zoom); - int dstH = (int) Math.ceil(h * zoom); - - if (dstW == 0 || dstH == 0) { - continue; - } - - // Don't create overlapping/duplicate tiles... - // - Always start tile grid at 0,0 - // - Always occupy entire tile, unless edge - - // Source (original) coordinates - int tileSrcX = x - x % tileSize; - int tileSrcY = y - y % tileSize; -// final int tileSrcW = Math.min(tileSize, image.getWidth() - tileSrcX); -// final int tileSrcH = Math.min(tileSize, image.getHeight() - tileSrcY); - - // Destination (display) coordinates - int tileDstX = (int) Math.floor(tileSrcX * zoom); - int tileDstY = (int) Math.floor(tileSrcY * zoom); -// final int tileDstW = (int) Math.round(tileSrcW * zoom); -// final int tileDstH = (int) Math.round(tileSrcH * zoom); - - List points = new ArrayList(4); - points.add(new Point(tileDstX, tileDstY)); - if (tileDstX != dstX) { - points.add(new Point(tileDstX + tileSize, tileDstY)); - } - if (tileDstY != dstY) { - points.add(new Point(tileDstX, tileDstY + tileSize)); - } - if (tileDstX != dstX && tileDstY != dstY) { - points.add(new Point(tileDstX + tileSize, tileDstY + tileSize)); - } - - for (final Point point : points) { - Tile tile = tiles.get(point); - - if (tile != null) { - if (tile.drawTo(g2)) { - continue; - } - else { - tiles.remove(point); - } - } - -// System.err.printf("Tile miss: [%d, %d]\n", dstX, dstY); - - // Dispatch to off-thread worker - final Map localTiles = tiles; - executorService2.submit(new Runnable() { - public void run() { - int tileSrcX = (int) Math.round(point.x / zoom); - int tileSrcY = (int) Math.round(point.y / zoom); - int tileSrcW = Math.min(tileSize, image.getWidth() - tileSrcX); - int tileSrcH = Math.min(tileSize, image.getHeight() - tileSrcY); - int tileDstW = (int) Math.round(tileSrcW * zoom); - int tileDstH = (int) Math.round(tileSrcH * zoom); - - try { - // TODO: Consider comparing zoom/local zoom - if (localTiles != tiles) { - return; // Return early after re-zoom - } - - if (localTiles.containsKey(point)) { -// System.err.println("Skipping tile, already producing..."); - return; - } - - // Test against current view rect, to avoid computing tiles that will be thrown away immediately - final Rectangle visibleRect = new Rectangle(); - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - visibleRect.setBounds(getVisibleRect()); - } - }); - - if (!visibleRect.intersects(new Rectangle(point.x, point.y, tileDstW, tileDstH))) { - return; - } - -// System.err.printf("Creating tile: [%d, %d]\n", tileDstX, tileDstY); - - BufferedImage temp = getGraphicsConfiguration().createCompatibleImage(tileDstW, tileDstH); - final Tile tile = new Tile(point.x, point.y, temp); - localTiles.put(point, tile); - - Graphics2D graphics = temp.createGraphics(); - try { - Object hint = g2.getRenderingHint(RenderingHints.KEY_INTERPOLATION); - - if (hint != null) { - graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint); - } - - graphics.scale(zoom, zoom); - graphics.drawImage(image.getSubimage(tileSrcX, tileSrcY, tileSrcW, tileSrcH), 0, 0, null); - } - finally { - graphics.dispose(); - } - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - repaint(10, tile.x, tile.y, tile.getWidth(), tile.getHeight()); - } - }); - } - catch (Throwable t) { - localTiles.remove(point); - System.err.println("Boooo: " + t.getMessage()); - } - } - }); - } - - } - } - } - catch (NullPointerException e) { -// e.printStackTrace(); - // Happens whenever apple.awt.OSXCachingSurfaceManager runs out of memory - // TODO: Figure out why repaint(x,y,w,h) doesn't work any more..? - System.err.println("Full repaint due to NullPointerException (probably out of memory)."); - repaint(); // NOTE: Might cause a brief flash while the component is redrawn - } - } - - private void repaintImage0(final Rectangle rect, final Graphics2D g2) { - g2.scale(zoom, zoom); - - try { - // Paint tiles of the image, to preserve memory - final int tileSize = 200; - - int tilesW = rect.width / tileSize; - int tilesH = rect.height / tileSize; - - for (int yTile = 0; yTile <= tilesH; yTile++) { - for (int xTile = 0; xTile <= tilesW; xTile++) { - // Image (source) coordinates - final int x = rect.x + xTile * tileSize; - final int y = rect.y + yTile * tileSize; - - final int w = xTile == tilesW ? Math.min(tileSize, rect.x + rect.width - x) : tileSize; - final int h = yTile == tilesH ? Math.min(tileSize, rect.y + rect.height - y) : tileSize; - - if (w == 0 || h == 0) { - continue; - } - -// System.err.printf("%04d, %04d, %04d, %04d%n", x, y, w, h); - - BufferedImage img = image.getSubimage(x, y, w, h); - g2.drawImage(img, x, y, null); - - } - } - } - catch (NullPointerException e) { -// e.printStackTrace(); - // Happens whenever apple.awt.OSXCachingSurfaceManager runs out of memory - // TODO: Figure out why repaint(x,y,w,h) doesn't work any more..? - System.err.println("Full repaint due to NullPointerException (probably out of memory)."); - repaint(); // NOTE: Might cause a brief flash while the component is redrawn - } - } - - @Override - public Dimension getPreferredSize() { - return new Dimension((int) (image.getWidth() * zoom), (int) (image.getHeight() * zoom)); - } - - public Dimension getPreferredScrollableViewportSize() { - return getPreferredSize(); - } - - public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { - return 10; - } - - public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { - switch (orientation) { - case SwingConstants.HORIZONTAL: - return visibleRect.width * 3 / 4; - case SwingConstants.VERTICAL: - default: - return visibleRect.height * 3 / 4; - } - } - - public boolean getScrollableTracksViewportWidth() { - return getWidth() > getPreferredSize().width; - } - - public boolean getScrollableTracksViewportHeight() { - return getHeight() > getPreferredSize().height; - } - } - - final static class SizedLRUMap extends LRUHashMap { - int currentSize; - int maxSize; - - public SizedLRUMap(int pMaxSize) { - super(); // Note: super.maxSize doesn't count... - maxSize = pMaxSize; - } - - - protected int sizeOf(final Object pValue) { - ImageComponent.Tile cached = (ImageComponent.Tile) pValue; - - if (cached == null) { - return 0; - } - - return cached.size(); - } - - @Override - public V put(K pKey, V pValue) { - currentSize += sizeOf(pValue); - - V old = super.put(pKey, pValue); - if (old != null) { - currentSize -= sizeOf(old); - } - return old; - } - - @Override - public V remove(Object pKey) { - V old = super.remove(pKey); - if (old != null) { - currentSize -= sizeOf(old); - } - return old; - } - - @Override - protected boolean removeEldestEntry(Map.Entry pEldest) { - if (maxSize <= currentSize) { // NOTE: maxSize here is mem size - removeLRU(); - } - return false; - } - - @Override - public void removeLRU() { - while (maxSize <= currentSize) { // NOTE: maxSize here is mem size - super.removeLRU(); - } - } - } - - private static class PaintDotsTask implements Runnable { - private final BufferedImage image; - private final int s; - private final int wstep; - private final Color[] colors; - private final Random random; - private final int last; - private final int first; - private final CountDownLatch latch; - - public PaintDotsTask(BufferedImage image, int s, int wstep, Color[] colors, Random random, int first, int last, CountDownLatch latch) { - this.image = image; - this.s = s; - this.wstep = wstep; - this.colors = colors; - this.random = random; - this.last = last; - this.first = first; - this.latch = latch; - } - - public void run() { - try { - paintDots0(image, s, wstep, colors, random, first, last); - } - finally { - latch.countDown(); - } - } - } - - private static class PaintBackgroundTask implements Runnable { - private final int w; - private final int h; - private final DataBuffer buffer; - private final boolean alpha; - private final int first; - private final int last; - private final CountDownLatch latch; - - public PaintBackgroundTask(int w, int h, DataBuffer buffer, boolean alpha, int first, int last, CountDownLatch latch) { - this.w = w; - this.h = h; - this.buffer = buffer; - this.alpha = alpha; - this.first = first; - this.last = last; - this.latch = latch; - } - - public void run() { - try { - paintBackground0(w, h, buffer, alpha, first, last); - } - finally { - latch.countDown(); - } - } - } - - private static class ConsoleProgressListener extends ProgressListenerBase { - static final int COLUMNS = System.getenv("COLUMNS") != null ? Integer.parseInt(System.getenv("COLUMNS")) - 2 : 78; - int left = COLUMNS; - - @Override - public void imageComplete(ImageReader source) { - for (; left > 0; left--) { - System.out.print("."); - } - System.out.println("]"); - } - - @Override - public void imageProgress(ImageReader source, float percentageDone) { - int progress = COLUMNS - Math.round(COLUMNS * percentageDone / 100f); - if (progress < left) { - for (; left > progress; left--) { - System.out.print("."); - } - } - } - - @Override - public void imageStarted(ImageReader source, int imageIndex) { - System.out.print("["); - } - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/MappedFileBuffer.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/MappedFileBuffer.java deleted file mode 100644 index ff1acafc..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/MappedFileBuffer.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (c) 2010, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.image; - -import com.twelvemonkeys.lang.Validate; - -import java.awt.image.DataBuffer; -import java.io.File; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.nio.*; -import java.nio.channels.FileChannel; - -/** - * A {@code DataBuffer} implementation that is backed by a memory mapped file. - * Memory will be allocated outside the normal JVM heap, allowing more efficient - * memory usage for large buffers. - * - * @author Harald Kuhr - * @author last modified by $Author: haraldk$ - * @version $Id: MappedFileBuffer.java,v 1.0 Jun 12, 2010 4:56:51 PM haraldk Exp$ - * - * @see java.nio.channels.FileChannel#map(java.nio.channels.FileChannel.MapMode, long, long) - */ -public abstract class MappedFileBuffer extends DataBuffer { - private final Buffer buffer; - - private MappedFileBuffer(final int type, final int size, final int numBanks) throws IOException { - super(type, Validate.isTrue(size >= 0, size, "Integer overflow for size: %d"), Validate.isTrue(numBanks >= 0, numBanks, "Number of banks must be positive")); - - int componentSize = DataBuffer.getDataTypeSize(type) / 8; - - // Create temp file to get a file handle to use for memory mapping - File tempFile = File.createTempFile(String.format("%s-", getClass().getSimpleName().toLowerCase()), ".tmp"); - - try { - RandomAccessFile raf = new RandomAccessFile(tempFile, "rw"); - - long length = ((long) size) * componentSize * numBanks; - - raf.setLength(length); - FileChannel channel = raf.getChannel(); - - // Map entire file into memory, let OS virtual memory/paging do the heavy lifting - MappedByteBuffer byteBuffer = channel.map(FileChannel.MapMode.READ_WRITE, 0, length); - - switch (type) { - case DataBuffer.TYPE_BYTE: - buffer = byteBuffer; - break; - case DataBuffer.TYPE_USHORT: - buffer = byteBuffer.asShortBuffer(); - break; - case DataBuffer.TYPE_INT: - buffer = byteBuffer.asIntBuffer(); - break; - default: - throw new IllegalArgumentException("Unsupported data type: " + type); - } - - // According to the docs, we can safely close the channel and delete the file now - channel.close(); - } - finally { - // NOTE: File can't be deleted right now on Windows, as the file is open. Let JVM clean up later - if (!tempFile.delete()) { - tempFile.deleteOnExit(); - } - } - } - - @Override - public String toString() { - return String.format("MappedFileBuffer: %s", buffer); - } - - // TODO: Is throws IOException a good idea? - - public static DataBuffer create(final int type, final int size, final int numBanks) throws IOException { - switch (type) { - case DataBuffer.TYPE_BYTE: - return new DataBufferByte(size, numBanks); - case DataBuffer.TYPE_USHORT: - return new DataBufferUShort(size, numBanks); - case DataBuffer.TYPE_INT: - return new DataBufferInt(size, numBanks); - default: - throw new IllegalArgumentException("Unsupported data type: " + type); - } - } - - final static class DataBufferByte extends MappedFileBuffer { - private final ByteBuffer buffer; - - public DataBufferByte(int size, int numBanks) throws IOException { - super(DataBuffer.TYPE_BYTE, size, numBanks); - buffer = (ByteBuffer) super.buffer; - } - - @Override - public int getElem(int bank, int i) { - return buffer.get(bank * size + i) & 0xff; - } - - @Override - public void setElem(int bank, int i, int val) { - buffer.put(bank * size + i, (byte) val); - } - } - - final static class DataBufferUShort extends MappedFileBuffer { - private final ShortBuffer buffer; - - public DataBufferUShort(int size, int numBanks) throws IOException { - super(DataBuffer.TYPE_USHORT, size, numBanks); - buffer = (ShortBuffer) super.buffer; - } - - @Override - public int getElem(int bank, int i) { - return buffer.get(bank * size + i) & 0xffff; - } - - @Override - public void setElem(int bank, int i, int val) { - buffer.put(bank * size + i, (short) val); - } - } - - final static class DataBufferInt extends MappedFileBuffer { - private final IntBuffer buffer; - - public DataBufferInt(int size, int numBanks) throws IOException { - super(DataBuffer.TYPE_INT, size, numBanks); - buffer = (IntBuffer) super.buffer; - } - - @Override - public int getElem(int bank, int i) { - return buffer.get(bank * size + i); - } - - @Override - public void setElem(int bank, int i, int val) { - buffer.put(bank * size + i, val); - } - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/MappedImageFactory.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/MappedImageFactory.java deleted file mode 100644 index 2dd4ac58..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/MappedImageFactory.java +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Copyright (c) 2010, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.image; - -import com.twelvemonkeys.lang.Validate; - -import javax.imageio.ImageTypeSpecifier; -import java.awt.*; -import java.awt.color.ColorSpace; -import java.awt.image.*; -import java.io.IOException; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Modifier; -import java.lang.reflect.UndeclaredThrowableException; - -/** - * A factory for creating {@link BufferedImage}s backed by memory mapped files. - * The data buffers will be allocated outside the normal JVM heap, allowing more efficient - * memory usage for large images. - * - * @author Harald Kuhr - * @author last modified by $Author: haraldk$ - * @version $Id: MappedImageFactory.java,v 1.0 May 26, 2010 5:07:01 PM haraldk Exp$ - */ -public final class MappedImageFactory { - - // TODO: Create a way to do ColorConvertOp (or other color space conversion) on these images. - // - Current implementation of CCOp delegates to internal sun.awt classes that assumes java.awt.DataBufferByte for type byte buffers :-/ - // - Might be possible (but slow) to copy parts to memory and do CCOp on these copies - - private static final boolean DEBUG = "true".equalsIgnoreCase(System.getProperty("com.twelvemonkeys.image.mapped.debug")); - - /* Constants for DirectColorModel masks, from BufferedImage. */ - private static final int DCM_RED_MASK = 0x00ff0000; - private static final int DCM_GREEN_MASK = 0x0000ff00; - private static final int DCM_BLUE_MASK = 0x000000ff; - private static final int DCM_ALPHA_MASK = 0xff000000; - private static final int DCM_565_RED_MASK = 0xf800; - private static final int DCM_565_GRN_MASK = 0x07E0; - private static final int DCM_565_BLU_MASK = 0x001F; - private static final int DCM_555_RED_MASK = 0x7C00; - private static final int DCM_555_GRN_MASK = 0x03E0; - private static final int DCM_555_BLU_MASK = 0x001F; - private static final int DCM_BGR_RED_MASK = 0x0000ff; - private static final int DCM_BGR_GRN_MASK = 0x00ff00; - private static final int DCM_BGR_BLU_MASK = 0xff0000; - - static final RasterFactory RASTER_FACTORY = createRasterFactory(); - - private MappedImageFactory() {} - - public static BufferedImage createCompatibleMappedImage(int width, int height, int type) throws IOException { - BufferedImage temp = new BufferedImage(1, 1, type); - return createCompatibleMappedImage(width, height, temp.getSampleModel().createCompatibleSampleModel(width, height), temp.getColorModel()); - } - - public static BufferedImage createCompatibleMappedImage(int width, int height, GraphicsConfiguration configuration, int transparency) throws IOException { - return createCompatibleMappedImage(width, height, configuration.getColorModel(transparency)); - } - - public static BufferedImage createCompatibleMappedImage(int width, int height, ImageTypeSpecifier type) throws IOException { - return createCompatibleMappedImage(width, height, type.getSampleModel(width, height), type.getColorModel()); - } - - static BufferedImage createCompatibleMappedImage(int width, int height, ColorModel cm) throws IOException { - return createCompatibleMappedImage(width, height, cm.createCompatibleSampleModel(width, height), cm); - } - - static BufferedImage createCompatibleMappedImage(int width, int height, SampleModel sm, ColorModel cm) throws IOException { - DataBuffer buffer = MappedFileBuffer.create(sm.getTransferType(), width * height * sm.getNumDataElements(), 1); - - return new BufferedImage(cm, RASTER_FACTORY.createRaster(sm, buffer, new Point()), cm.isAlphaPremultiplied(), null); - } - - /** - *

- * Returns the {@code BufferedImage} image type that is compatible with the data in {@code image}. - * This method will return compatible types, even if {@code BufferedImage.getType()} returns - * {@code BufferedImage.TYPE_CUSTOM}. - *

- *

- * This method is defined to work so that, for any valid {@code BufferedImage} type - * (except {@code BufferedImage.TYPE_CUSTOM}), the following is {@code true}: - *
- * {@code getCompatibleBufferedImageType(createCompatibleMappedImage(w, h, type)) == type} - *

- *

- * If no standard type is compatible with the image data, {@code BufferedImage.TYPE_CUSTOM} is returned. - *

- * - * @param image the image to test, may not be {@code null}. - * - * @return the {@code BufferedImage} type. - * - * @throws java.lang.IllegalArgumentException if {@code image} is {@code null}. - * - * @see java.awt.image.BufferedImage#getType() - */ - public static int getCompatibleBufferedImageType(final BufferedImage image) { - Validate.notNull(image, "image"); - - WritableRaster raster = image.getRaster(); - SampleModel sm = raster.getSampleModel(); - int numBands = raster.getNumBands(); - - ColorModel cm = image.getColorModel(); - ColorSpace cs = cm.getColorSpace(); - boolean isAlphaPre = cm.isAlphaPremultiplied(); - int csType = cs.getType(); - - int dataType = raster.getDataBuffer().getDataType(); - - if (csType != ColorSpace.TYPE_RGB) { - if (csType == ColorSpace.TYPE_GRAY && cm instanceof ComponentColorModel) { - if (sm instanceof ComponentSampleModel && ((ComponentSampleModel) sm).getPixelStride() != numBands) { - return BufferedImage.TYPE_CUSTOM; - } - else if (dataType == DataBuffer.TYPE_BYTE && raster.getNumBands() == 1 && - cm.getComponentSize(0) == 8 && ((ComponentSampleModel) sm).getPixelStride() == 1) { - return BufferedImage.TYPE_BYTE_GRAY; - } - else if (dataType == DataBuffer.TYPE_USHORT && raster.getNumBands() == 1 && - cm.getComponentSize(0) == 16 && ((ComponentSampleModel) sm).getPixelStride() == 1) { - return BufferedImage.TYPE_USHORT_GRAY; - } - } - else { - return BufferedImage.TYPE_CUSTOM; - } - } - - if ((dataType == DataBuffer.TYPE_INT) && (numBands == 3 || numBands == 4)) { - // Check if the raster params and the color model are correct - int pixSize = cm.getPixelSize(); - - if (cm instanceof DirectColorModel && sm.getNumDataElements() == 1 && (pixSize == 32 || pixSize == 24)) { - // Now check on the DirectColorModel params - DirectColorModel dcm = (DirectColorModel) cm; - int rmask = dcm.getRedMask(); - int gmask = dcm.getGreenMask(); - int bmask = dcm.getBlueMask(); - - if (rmask == DCM_RED_MASK && gmask == DCM_GREEN_MASK && bmask == DCM_BLUE_MASK) { - if (dcm.getAlphaMask() == DCM_ALPHA_MASK) { - return isAlphaPre ? BufferedImage.TYPE_INT_ARGB_PRE : BufferedImage.TYPE_INT_ARGB; - } - else if (!dcm.hasAlpha()) { - // No Alpha - return BufferedImage.TYPE_INT_RGB; - } - } - else if (rmask == DCM_BGR_RED_MASK && gmask == DCM_BGR_GRN_MASK && bmask == DCM_BGR_BLU_MASK) { - if (!dcm.hasAlpha()) { - return BufferedImage.TYPE_INT_BGR; - } - } - } - } - else if ((cm instanceof IndexColorModel) && (numBands == 1) && (!cm.hasAlpha() || !isAlphaPre)) { - IndexColorModel icm = (IndexColorModel) cm; - int pixSize = icm.getPixelSize(); - - if (dataType == DataBuffer.TYPE_BYTE && sm instanceof MultiPixelPackedSampleModel) { - return BufferedImage.TYPE_BYTE_BINARY; - } - if (dataType == DataBuffer.TYPE_BYTE && sm instanceof ComponentSampleModel) { - ComponentSampleModel csm = (ComponentSampleModel) sm; - - if (csm.getPixelStride() == 1 && pixSize <= 8) { - return BufferedImage.TYPE_BYTE_INDEXED; - } - } - } - else if ((dataType == DataBuffer.TYPE_USHORT) && - (cm instanceof DirectColorModel) && (numBands == 3) && !cm.hasAlpha()) { - DirectColorModel dcm = (DirectColorModel) cm; - - if (dcm.getRedMask() == DCM_565_RED_MASK && - dcm.getGreenMask() == DCM_565_GRN_MASK && dcm.getBlueMask() == DCM_565_BLU_MASK) { - return BufferedImage.TYPE_USHORT_565_RGB; - } - else if (dcm.getRedMask() == DCM_555_RED_MASK && - dcm.getGreenMask() == DCM_555_GRN_MASK && dcm.getBlueMask() == DCM_555_BLU_MASK) { - return BufferedImage.TYPE_USHORT_555_RGB; - } - } - else if (dataType == DataBuffer.TYPE_BYTE && cm instanceof ComponentColorModel && - raster.getSampleModel() instanceof PixelInterleavedSampleModel && (numBands == 3 || numBands == 4)) { - ComponentColorModel ccm = (ComponentColorModel) cm; - PixelInterleavedSampleModel csm = (PixelInterleavedSampleModel) raster.getSampleModel(); - - int[] offs = csm.getBandOffsets(); - int[] nBits = ccm.getComponentSize(); - boolean is8bit = true; - - for (int i = 0; i < numBands; i++) { - if (nBits[i] != 8) { - is8bit = false; - break; - } - } - - if (is8bit && csm.getPixelStride() == numBands && - offs[0] == numBands - 1 && offs[1] == numBands - 2 && offs[2] == numBands - 3) { - if (numBands == 3 && !ccm.hasAlpha()) { - return BufferedImage.TYPE_3BYTE_BGR; - } - else if (offs[3] == 0 && ccm.hasAlpha()) { - return isAlphaPre ? BufferedImage.TYPE_4BYTE_ABGR_PRE : BufferedImage.TYPE_4BYTE_ABGR; - } - } - } - - return BufferedImage.TYPE_CUSTOM; - } - - private static RasterFactory createRasterFactory() { - try { - // Try to instantiate, will throw LinkageError if it fails - return new SunRasterFactory(); - } - catch (LinkageError e) { - if (DEBUG) { - e.printStackTrace(); - } - - System.err.println("Could not instantiate SunWritableRaster, falling back to GenericWritableRaster."); - } - - // Fall back - return new GenericRasterFactory(); - } - - static interface RasterFactory { - WritableRaster createRaster(SampleModel model, DataBuffer buffer, Point origin); - } - - /** - * Generic implementation that should work for any JRE, and creates a custom subclass of {@link WritableRaster}. - */ - static final class GenericRasterFactory implements RasterFactory { - public WritableRaster createRaster(final SampleModel model, final DataBuffer buffer, final Point origin) { - return new GenericWritableRaster(model, buffer, origin); - } - } - - /** - * Sun/Oracle JRE-specific implementation that creates {@code sun.awt.image.SunWritableRaster}. - * Callers must catch {@link LinkageError}. - */ - static final class SunRasterFactory implements RasterFactory { - final private Constructor factoryMethod = getFactoryMethod(); - - @SuppressWarnings("unchecked") - private static Constructor getFactoryMethod() { - try { - Class cls = Class.forName("sun.awt.image.SunWritableRaster"); - - if (Modifier.isAbstract(cls.getModifiers())) { - throw new IncompatibleClassChangeError("sun.awt.image.SunWritableRaster has become abstract and can't be instantiated"); - } - - return (Constructor) cls.getConstructor(SampleModel.class, DataBuffer.class, Point.class); - } - catch (ClassNotFoundException e) { - throw new NoClassDefFoundError(e.getMessage()); - } - catch (NoSuchMethodException e) { - throw new NoSuchMethodError(e.getMessage()); - } - } - - public WritableRaster createRaster(final SampleModel model, final DataBuffer buffer, final Point origin) { - try { - return factoryMethod.newInstance(model, buffer, origin); - } - catch (InstantiationException e) { - throw new Error("Could not create SunWritableRaster: ", e); // Should never happen, as we test for abstract class - } - catch (IllegalAccessException e) { - throw new Error("Could not create SunWritableRaster: ", e); // Should never happen, only public constructors are reflected - } - catch (InvocationTargetException e) { - // Unwrap to allow normal exception flow - Throwable cause = e.getCause(); - - if (cause instanceof RuntimeException) { - throw (RuntimeException) cause; - } - else if (cause instanceof Error) { - throw (Error) cause; - } - - throw new UndeclaredThrowableException(cause); - } - } - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/NoiseFilter.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/NoiseFilter.java deleted file mode 100644 index 73c8d50b..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/NoiseFilter.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2012, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* -Copyright 2006 Jerry Huxtable - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ -package com.twelvemonkeys.image; - -import java.awt.image.BufferedImage; -import java.awt.image.WritableRaster; -import java.util.Random; - -/** - * NoiseFilter - * - * @author Harald Kuhr - * @author last modified by $Author: haraldk$ - * @version $Id: NoiseFilter.java,v 1.0 15.06.12 22:59 haraldk Exp$ - */ -public class NoiseFilter extends AbstractFilter { - - /** - * Gaussian distribution for the noise. - */ - public final static int GAUSSIAN = 0; - - /** - * Uniform distribution for the noise. - */ - public final static int UNIFORM = 1; - - private int amount = 25; - private int distribution = UNIFORM; - private boolean monochrome = false; - private float density = 1; - private Random randomNumbers = new Random(); - - public NoiseFilter() { - } - - /** - * Set the amount of effect. - * - * @param amount the amount - * @min-value 0 - * @max-value 1 - * @see #getAmount - */ - public void setAmount(int amount) { - this.amount = amount; - } - - /** - * Get the amount of noise. - * - * @return the amount - * @see #setAmount - */ - public int getAmount() { - return amount; - } - - /** - * Set the distribution of the noise. - * - * @param distribution the distribution - * @see #getDistribution - */ - public void setDistribution(int distribution) { - this.distribution = distribution; - } - - /** - * Get the distribution of the noise. - * - * @return the distribution - * @see #setDistribution - */ - public int getDistribution() { - return distribution; - } - - /** - * Set whether to use monochrome noise. - * - * @param monochrome true for monochrome noise - * @see #getMonochrome - */ - public void setMonochrome(boolean monochrome) { - this.monochrome = monochrome; - } - - /** - * Get whether to use monochrome noise. - * - * @return true for monochrome noise - * @see #setMonochrome - */ - public boolean getMonochrome() { - return monochrome; - } - - /** - * Set the density of the noise. - * - * @param density the density - * @see #getDensity - */ - public void setDensity(float density) { - this.density = density; - } - - /** - * Get the density of the noise. - * - * @return the density - * @see #setDensity - */ - public float getDensity() { - return density; - } - - private int random() { - return (int) (((distribution == GAUSSIAN ? randomNumbers.nextGaussian() : 2 * randomNumbers.nextFloat() - 1)) * amount); - } - - private static int clamp(int x) { - if (x < 0) { - return 0; - } - else if (x > 0xff) { - return 0xff; - } - return x; - } - - public int filterRGB(int x, int y, int rgb) { - if (randomNumbers.nextFloat() <= density) { - int a = rgb & 0xff000000; - int r = (rgb >> 16) & 0xff; - int g = (rgb >> 8) & 0xff; - int b = rgb & 0xff; - - if (monochrome) { - int n = random(); - r = clamp(r + n); - g = clamp(g + n); - b = clamp(b + n); - } - else { - r = clamp(r + random()); - g = clamp(g + random()); - b = clamp(b + random()); - } - return a | (r << 16) | (g << 8) | b; - } - return rgb; - } - - public BufferedImage filter(BufferedImage src, BufferedImage dst) { - int width = src.getWidth(); - int height = src.getHeight(); - int type = src.getType(); - WritableRaster srcRaster = src.getRaster(); - - if (dst == null) { - dst = createCompatibleDestImage(src, null); - } - WritableRaster dstRaster = dst.getRaster(); - - int[] inPixels = new int[width]; - for (int y = 0; y < height; y++) { - // We try to avoid calling getRGB on images as it causes them to become unmanaged, causing horrible performance problems. - if (type == BufferedImage.TYPE_INT_ARGB) { - srcRaster.getDataElements(0, y, width, 1, inPixels); - for (int x = 0; x < width; x++) { - inPixels[x] = filterRGB(x, y, inPixels[x]); - } - dstRaster.setDataElements(0, y, width, 1, inPixels); - } - else { - src.getRGB(0, y, width, 1, inPixels, 0, width); - for (int x = 0; x < width; x++) { - inPixels[x] = filterRGB(x, y, inPixels[x]); - } - dst.setRGB(0, y, width, 1, inPixels, 0, width); - } - } - - return dst; - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/SubsampleTester.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/SubsampleTester.java deleted file mode 100755 index be8e52f2..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/SubsampleTester.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.image; - -import javax.imageio.ImageIO; -import javax.imageio.ImageReadParam; -import javax.imageio.ImageReader; -import javax.imageio.stream.ImageInputStream; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; -import java.util.Iterator; - -/** - * SubsampleTester - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/image/SubsampleTester.java#1 $ - */ -public class SubsampleTester { - - // Initial testing shows we need at least 9 pixels (sampleFactor == 3) to make a good looking image.. - // Also, using Lanczos is much better than (and allmost as fast as) halving using AffineTransform - // - But I guess those numbers depend on the data type of the input image... - - public static void main(String[] pArgs) throws IOException { - // To/from larger than or equal to 4x4 - //ImageUtil.createResampled(new BufferedImage(5, 5, BufferedImage.TYPE_INT_ARGB), 4, 4, BufferedImage.SCALE_SMOOTH); - //ImageUtil.createResampled(new BufferedImage(4, 4, BufferedImage.TYPE_INT_ARGB), 5, 5, BufferedImage.SCALE_SMOOTH); - - // To/from smaller than or equal to 4x4 with fast scale - //ImageUtil.createResampled(new BufferedImage(3, 3, BufferedImage.TYPE_INT_ARGB), 10, 10, BufferedImage.SCALE_FAST); - //ImageUtil.createResampled(new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB), 3, 3, BufferedImage.SCALE_FAST); - - // To/from smaller than or equal to 4x4 with default scale - //ImageUtil.createResampled(new BufferedImage(3, 3, BufferedImage.TYPE_INT_ARGB), 10, 10, BufferedImage.SCALE_DEFAULT); - //ImageUtil.createResampled(new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB), 3, 3, BufferedImage.SCALE_DEFAULT); - - // To/from smaller than or equal to 4x4 with smooth scale - try { - ImageUtil.createResampled(new BufferedImage(3, 3, BufferedImage.TYPE_INT_ARGB), 10, 10, BufferedImage.SCALE_SMOOTH); - } - catch (IndexOutOfBoundsException e) { - e.printStackTrace(); - } - //try { - // ImageUtil.createResampled(new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB), 3, 3, BufferedImage.SCALE_SMOOTH); - //} - //catch (IndexOutOfBoundsException e) { - // e.printStackTrace(); - // return; - //} - - File input = new File(pArgs[0]); - ImageInputStream stream = ImageIO.createImageInputStream(input); - - Iterator readers = ImageIO.getImageReaders(stream); - if (readers.hasNext()) { - if (stream == null) { - return; - } - ImageReader reader = readers.next(); - reader.setInput(stream); - - ImageReadParam param = reader.getDefaultReadParam(); - - for (int i = 0; i < 25; i++) { - //readImage(pArgs, reader, param); - } - - long start = System.currentTimeMillis(); - - BufferedImage image = readImage(pArgs, reader, param); - - long end = System.currentTimeMillis(); - - System.out.println("elapsed time: " + (end - start) + " ms"); - - int subX = param.getSourceXSubsampling(); - int subY = param.getSourceYSubsampling(); - - System.out.println("image: " + image); - - //ImageIO.write(image, "png", new File(input.getParentFile(), input.getName().replace('.', '_') + "_new.png")); - - ConvolveTester.showIt(image, input.getName() + (subX > 1 || subY > 1 ? " (subsampled " + subX + " by " + subY + ")" : "")); - } - else { - System.err.println("No reader found for input: " + input.getAbsolutePath()); - } - } - - private static BufferedImage readImage(final String[] pArgs, final ImageReader pReader, final ImageReadParam pParam) throws IOException { - double sampleFactor; // Minimum number of samples (in each dimension) pr pixel in output - - int width = pArgs.length > 1 ? Integer.parseInt(pArgs[1]) : 300; - int height = pArgs.length > 2 ? Integer.parseInt(pArgs[2]) : 200; - - if (pArgs.length > 3 && (sampleFactor = Double.parseDouble(pArgs[3])) > 0) { - int originalWidth = pReader.getWidth(0); - int originalHeight = pReader.getHeight(0); - - System.out.println("originalWidth: " + originalWidth); - System.out.println("originalHeight: " + originalHeight); - - int subX = (int) Math.max(originalWidth / (double) (width * sampleFactor), 1.0); - int subY = (int) Math.max(originalHeight / (double) (height * sampleFactor), 1.0); - - if (subX > 1 || subY > 1) { - System.out.println("subX: " + subX); - System.out.println("subY: " + subY); - pParam.setSourceSubsampling(subX, subY, subX > 1 ? subX / 2 : 0, subY > 1 ? subY / 2 : 0); - } - } - - BufferedImage image = pReader.read(0, pParam); - - System.out.println("image: " + image); - - int algorithm = BufferedImage.SCALE_DEFAULT; - if (pArgs.length > 4) { - if ("smooth".equals(pArgs[4].toLowerCase())) { - algorithm = BufferedImage.SCALE_SMOOTH; - } - else if ("fast".equals(pArgs[4].toLowerCase())) { - algorithm = BufferedImage.SCALE_FAST; - } - } - - if (image.getWidth() != width || image.getHeight() != height) { - image = ImageUtil.createScaled(image, width, height, algorithm); - } - - return image; - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/inv_cmap.c b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/inv_cmap.c deleted file mode 100755 index efdc5600..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/inv_cmap.c +++ /dev/null @@ -1,524 +0,0 @@ -/* - * This software is copyrighted as noted below. It may be freely copied, - * modified, and redistributed, provided that the copyright notice is - * preserved on all copies. - * - * There is no warranty or other guarantee of fitness for this software, - * it is provided solely "as is". Bug reports or fixes may be sent - * to the author, who may or may not act on them as he desires. - * - * You may not include this software in a program or other software product - * without supplying the source, or without informing the end-user that the - * source is available for no extra charge. - * - * If you modify this software, you should include a notice giving the - * name of the person performing the modification, the date of modification, - * and the reason for such modification. - */ -/* - * inv_cmap.c - Compute an inverse colormap. - * - * Author: Spencer W. Thomas - * EECS Dept. - * University of Michigan - * Date: Thu Sep 20 1990 - * Copyright (c) 1990, University of Michigan - * - * $Id: inv_cmap.c,v 3.0.1.3 1992/04/30 14:07:28 spencer Exp $ - */ - -#include -#include - - -static int bcenter, gcenter, rcenter; -static long gdist, rdist, cdist; -static long cbinc, cginc, crinc; -static unsigned long *gdp, *rdp, *cdp; -static unsigned char *grgbp, *rrgbp, *crgbp; -static gstride, rstride; -static long x, xsqr, colormax; -static int cindex; - -#ifdef USE_PROTOTYPES -static void maxfill( unsigned long *, long ); -static int redloop( void ); -static int greenloop( int ); -static int blueloop( int ); -#else -static void maxfill(); -static int redloop(); -static int greenloop(); -static int blueloop(); -#endif - - -/***************************************************************** - * TAG( inv_cmap ) - * - * Compute an inverse colormap efficiently. - * Inputs: - * colors: Number of colors in the forward colormap. - * colormap: The forward colormap. - * bits: Number of quantization bits. The inverse - * colormap will have (2^bits)^3 entries. - * dist_buf: An array of (2^bits)^3 long integers to be - * used as scratch space. - * Outputs: - * rgbmap: The output inverse colormap. The entry - * rgbmap[(r<<(2*bits)) + (g<> nbits; - gcenter = colormap[1][cindex] >> nbits; - bcenter = colormap[2][cindex] >> nbits; - - rdist = colormap[0][cindex] - (rcenter * x + x/2); - gdist = colormap[1][cindex] - (gcenter * x + x/2); - cdist = colormap[2][cindex] - (bcenter * x + x/2); - cdist = rdist*rdist + gdist*gdist + cdist*cdist; - - crinc = 2 * ((rcenter + 1) * xsqr - (colormap[0][cindex] * x)); - cginc = 2 * ((gcenter + 1) * xsqr - (colormap[1][cindex] * x)); - cbinc = 2 * ((bcenter + 1) * xsqr - (colormap[2][cindex] * x)); - - /* Array starting points. */ - cdp = dist_buf + rcenter * rstride + gcenter * gstride + bcenter; - crgbp = rgbmap + rcenter * rstride + gcenter * gstride + bcenter; - - (void)redloop(); - } -} - -/* redloop -- loop up and down from red center. */ -static int -redloop() -{ - int detect; - int r; - int first; - long txsqr = xsqr + xsqr; - static long rxx; - - detect = 0; - - /* Basic loop up. */ - for ( r = rcenter, rdist = cdist, rxx = crinc, - rdp = cdp, rrgbp = crgbp, first = 1; - r < colormax; - r++, rdp += rstride, rrgbp += rstride, - rdist += rxx, rxx += txsqr, first = 0 ) - { - if ( greenloop( first ) ) - detect = 1; - else if ( detect ) - break; - } - - /* Basic loop down. */ - for ( r = rcenter - 1, rxx = crinc - txsqr, rdist = cdist - rxx, - rdp = cdp - rstride, rrgbp = crgbp - rstride, first = 1; - r >= 0; - r--, rdp -= rstride, rrgbp -= rstride, - rxx -= txsqr, rdist -= rxx, first = 0 ) - { - if ( greenloop( first ) ) - detect = 1; - else if ( detect ) - break; - } - - return detect; -} - -/* greenloop -- loop up and down from green center. */ -static int -greenloop( restart ) -int restart; -{ - int detect; - int g; - int first; - long txsqr = xsqr + xsqr; - static int here, min, max; - static long ginc, gxx, gcdist; /* "gc" variables maintain correct */ - static unsigned long *gcdp; /* values for bcenter position, */ - static unsigned char *gcrgbp; /* despite modifications by blueloop */ - /* to gdist, gdp, grgbp. */ - - if ( restart ) - { - here = gcenter; - min = 0; - max = colormax - 1; - ginc = cginc; - } - - detect = 0; - - /* Basic loop up. */ - for ( g = here, gcdist = gdist = rdist, gxx = ginc, - gcdp = gdp = rdp, gcrgbp = grgbp = rrgbp, first = 1; - g <= max; - g++, gdp += gstride, gcdp += gstride, grgbp += gstride, gcrgbp += gstride, - gdist += gxx, gcdist += gxx, gxx += txsqr, first = 0 ) - { - if ( blueloop( first ) ) - { - if ( !detect ) - { - /* Remember here and associated data! */ - if ( g > here ) - { - here = g; - rdp = gcdp; - rrgbp = gcrgbp; - rdist = gcdist; - ginc = gxx; - } - detect = 1; - } - } - else if ( detect ) - { - break; - } - } - - /* Basic loop down. */ - for ( g = here - 1, gxx = ginc - txsqr, gcdist = gdist = rdist - gxx, - gcdp = gdp = rdp - gstride, gcrgbp = grgbp = rrgbp - gstride, - first = 1; - g >= min; - g--, gdp -= gstride, gcdp -= gstride, grgbp -= gstride, gcrgbp -= gstride, - gxx -= txsqr, gdist -= gxx, gcdist -= gxx, first = 0 ) - { - if ( blueloop( first ) ) - { - if ( !detect ) - { - /* Remember here! */ - here = g; - rdp = gcdp; - rrgbp = gcrgbp; - rdist = gcdist; - ginc = gxx; - detect = 1; - } - } - else if ( detect ) - { - break; - } - } - - - return detect; -} - -/* blueloop -- loop up and down from blue center. */ -static int -blueloop( restart ) -int restart; -{ - int detect; - register unsigned long *dp; - register unsigned char *rgbp; - register long bdist, bxx; - register int b, i = cindex; - register long txsqr = xsqr + xsqr; - register int lim; - static int here, min, max; - static long binc; - - if ( restart ) - { - here = bcenter; - min = 0; - max = colormax - 1; - binc = cbinc; - } - - detect = 0; - - /* Basic loop up. */ - /* First loop just finds first applicable cell. */ - for ( b = here, bdist = gdist, bxx = binc, dp = gdp, rgbp = grgbp, lim = max; - b <= lim; - b++, dp++, rgbp++, - bdist += bxx, bxx += txsqr ) - { - if ( *dp > bdist ) - { - /* Remember new 'here' and associated data! */ - if ( b > here ) - { - here = b; - gdp = dp; - grgbp = rgbp; - gdist = bdist; - binc = bxx; - } - detect = 1; - break; - } - } - /* Second loop fills in a run of closer cells. */ - for ( ; - b <= lim; - b++, dp++, rgbp++, - bdist += bxx, bxx += txsqr ) - { - if ( *dp > bdist ) - { - *dp = bdist; - *rgbp = i; - } - else - { - break; - } - } - - /* Basic loop down. */ - /* Do initializations here, since the 'find' loop might not get - * executed. - */ - lim = min; - b = here - 1; - bxx = binc - txsqr; - bdist = gdist - bxx; - dp = gdp - 1; - rgbp = grgbp - 1; - /* The 'find' loop is executed only if we didn't already find - * something. - */ - if ( !detect ) - for ( ; - b >= lim; - b--, dp--, rgbp--, - bxx -= txsqr, bdist -= bxx ) - { - if ( *dp > bdist ) - { - /* Remember here! */ - /* No test for b against here necessary because b < - * here by definition. - */ - here = b; - gdp = dp; - grgbp = rgbp; - gdist = bdist; - binc = bxx; - detect = 1; - break; - } - } - /* The 'update' loop. */ - for ( ; - b >= lim; - b--, dp--, rgbp--, - bxx -= txsqr, bdist -= bxx ) - { - if ( *dp > bdist ) - { - *dp = bdist; - *rgbp = i; - } - else - { - break; - } - } - - - /* If we saw something, update the edge trackers. */ - - return detect; -} - -static void -maxfill( buffer, side ) -unsigned long *buffer; -long side; -{ - register unsigned long maxv = ~0L; - register long i; - register unsigned long *bp; - - for ( i = side * side * side, bp = buffer; - i > 0; - i--, bp++ ) - *bp = maxv; -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/io/FileLockingTest.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/io/FileLockingTest.java deleted file mode 100755 index 101a1179..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/io/FileLockingTest.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2009, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.io; - -import java.io.*; -import java.nio.channels.Channels; -import java.nio.channels.FileChannel; -import java.nio.channels.FileLock; - -/** - * FileLockingTest - * - * @author Harald Kuhr - * @author last modified by $Author: haraldk$ - * @version $Id: FileLockingTest.java,v 1.0 May 12, 2009 7:15:38 PM haraldk Exp$ - */ -public class FileLockingTest { - public static void main(final String[] pArgs) throws IOException { - FileChannel channel = new RandomAccessFile(pArgs[0], "rw").getChannel(); - FileLock lock = channel.tryLock(0, Long.MAX_VALUE, pArgs.length <= 1 || !"false".equalsIgnoreCase(pArgs[1])); // Shared lock for entire file - - System.out.println("lock: " + lock); - - if (lock != null) { - System.in.read(); - - InputStream stream = Channels.newInputStream(channel); - BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); - String line; - while ((line = reader.readLine()) != null) { - System.out.println(line); - } - } - else { - System.out.println("Already locked"); - } - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/io/FileMonitor.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/io/FileMonitor.java deleted file mode 100755 index 84584c78..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/io/FileMonitor.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2009, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.io; - -import java.io.File; - -/** - * Allows monitoring a file on the file system. - * - * @author Harald Kuhr - * @author last modified by $Author: haraldk$ - * @version $Id: FileMonitor.java,v 1.0 May 12, 2009 6:58:55 PM haraldk Exp$ - */ -public class FileMonitor { - - - - /** - * Listens for changes to a file. - * - */ - public interface FileChangeListener { - - public void fileCreated(File pFile) throws Exception; // TODO: Is this a good thing? - - public void fileUpdated(File pFile) throws Exception; - - public void fileDeleted(File pFile) throws Exception; - } - -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/io/StringInputStream.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/io/StringInputStream.java deleted file mode 100644 index 61e0fb50..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/io/StringInputStream.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.twelvemonkeys.io; - -import com.twelvemonkeys.lang.Validate; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.Charset; -import java.nio.charset.CharsetEncoder; - -/** - * An {@code InputStream} that reads bytes from a {@code String}. - * - * This class properly converts characters into bytes using a {@code Charset}, - * unlike the deprecated {@link java.io.StringBufferInputStream}. - * - * @author Harald Kuhr - * @author last modified by $Author: haraldk$ - * @version $Id: StringInputStream.java,v 1.0 03.09.13 10:19 haraldk Exp$ - */ -public final class StringInputStream extends InputStream { - - private final CharBuffer chars; - private final CharsetEncoder encoder; - private final ByteBuffer buffer; - - public StringInputStream(final String string, final Charset charset) { - this(Validate.notNull(string, "string"), 0, string.length(), charset); - } - - public StringInputStream(final String string, int offset, int length, final Charset charset) { - chars = CharBuffer.wrap(Validate.notNull(string, "string"), offset, offset + length); - encoder = Validate.notNull(charset, "charset").newEncoder(); - buffer = ByteBuffer.allocate(256); - buffer.flip(); - } - - private boolean fillBuffer() { - buffer.clear(); - encoder.encode(chars, buffer, chars.hasRemaining()); // TODO: Do we have to care about the result? - buffer.flip(); - - return buffer.hasRemaining(); - } - - private boolean ensureBuffer() { - return buffer.hasRemaining() || (chars.hasRemaining() && fillBuffer()); - } - - @Override - public int read() throws IOException { - if (!ensureBuffer()) { - return -1; - } - - return buffer.get() & 0xff; - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - if (!ensureBuffer()) { - return -1; - } - - int count = Math.min(buffer.remaining(), len); - buffer.get(b, off, count); - return count; - } - - @Override - public long skip(long len) throws IOException { - if (!ensureBuffer()) { - return -1; - } - - int count = (int) Math.min(buffer.remaining(), len); - int position = buffer.position(); - buffer.position(position + count); - return count; - } - - @Override - public int available() throws IOException { - return buffer.remaining(); - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/io/enc/DeflateEncoder.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/io/enc/DeflateEncoder.java deleted file mode 100644 index 176cf8b4..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/io/enc/DeflateEncoder.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.io.enc; - -import java.io.OutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.zip.Deflater; - -/** - * {@code Encoder} implementation for standard DEFLATE encoding. - *

- * - * @author Harald Kuhr - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/io/enc/DeflateEncoder.java#2 $ - * - * @see RFC 1951 - * @see Deflater - * @see InflateDecoder - * @see java.util.zip.DeflaterOutputStream - */ -final class DeflateEncoder implements Encoder { - - private final Deflater deflater; - private final byte[] buffer = new byte[1024]; - - public DeflateEncoder() { - this(new Deflater(Deflater.DEFAULT_COMPRESSION, true)); // TODO: Should we use "no wrap"? - } - - public DeflateEncoder(final Deflater pDeflater) { - if (pDeflater == null) { - throw new IllegalArgumentException("deflater == null"); - } - - deflater = pDeflater; - } - - public void encode(final OutputStream stream, ByteBuffer buffer) - throws IOException - { - System.out.println("DeflateEncoder.encode"); - deflater.setInput(buffer.array(), buffer.arrayOffset() + buffer.position(), buffer.remaining()); - flushInputToStream(stream); - } - - private void flushInputToStream(final OutputStream pStream) throws IOException { - System.out.println("DeflateEncoder.flushInputToStream"); - - if (deflater.needsInput()) { - System.out.println("Foo"); - } - - while (!deflater.needsInput()) { - int deflated = deflater.deflate(buffer, 0, buffer.length); - pStream.write(buffer, 0, deflated); - System.out.println("flushed " + deflated); - } - } - -// public void flush() { -// deflater.finish(); -// } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/io/enc/InflateDecoder.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/io/enc/InflateDecoder.java deleted file mode 100644 index e69b8b68..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/io/enc/InflateDecoder.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.io.enc; - -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.util.zip.DataFormatException; -import java.util.zip.Inflater; - -/** - * {@code Decoder} implementation for standard DEFLATE encoding. - *

- * - * @see RFC 1951 - * - * @see Inflater - * @see DeflateEncoder - * @see java.util.zip.InflaterInputStream - * - * @author Harald Kuhr - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/io/enc/InflateDecoder.java#2 $ - */ -final class InflateDecoder implements Decoder { - - private final Inflater inflater; - - private final byte[] buffer; - - /** - * Creates an {@code InflateDecoder} - * - */ - public InflateDecoder() { - this(new Inflater(true)); - } - - /** - * Creates an {@code InflateDecoder} - * - * @param pInflater the inflater instance to use - */ - public InflateDecoder(final Inflater pInflater) { - if (pInflater == null) { - throw new IllegalArgumentException("inflater == null"); - } - - inflater = pInflater; - buffer = new byte[1024]; - } - - public int decode(final InputStream stream, final ByteBuffer buffer) throws IOException { - try { - int decoded; - - while ((decoded = inflater.inflate(buffer.array(), buffer.arrayOffset(), buffer.capacity())) == 0) { - if (inflater.finished() || inflater.needsDictionary()) { - return 0; - } - - if (inflater.needsInput()) { - fill(stream); - } - } - - return decoded; - } - catch (DataFormatException e) { - String message = e.getMessage(); - throw new DecodeException(message != null ? message : "Invalid ZLIB data format", e); - } - } - - private void fill(final InputStream pStream) throws IOException { - int available = pStream.read(buffer, 0, buffer.length); - - if (available == -1) { - throw new EOFException("Unexpected end of ZLIB stream"); - } - - inflater.setInput(buffer, 0, available); - } -} \ No newline at end of file diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/lang/DuckType.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/lang/DuckType.java deleted file mode 100755 index 97eb33d1..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/lang/DuckType.java +++ /dev/null @@ -1,468 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.lang; - -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; -import java.util.*; - -/** - * “If it walks like a duck, looks like a duck, quacks like a duck, it must be…”. - *

- * Based on an idea found at - * The Visual Editor - * - * @author Harald Kuhr - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-sandbox/src/main/java/com/twelvemonkeys/lang/DuckType.java#1 $ - * - * @see java.lang.reflect.Proxy - */ -public final class DuckType { - /* - EXAMPLE: - public ImageMgr(Object receiver, Image image) { - if (!DuckType.instanceOf(IImageHolder.class, receiver)) { - throw new ClassCastException("Cannot implement IImageHolder"); - } - - this.image = image; - - IImageHolder imageHolder = (IImageHolder) DuckType.implement(IImageHolder.class, receiver); - imageHolder.setImage(image); - imageHolder.addDisposeListener(this); - } - */ - - // TODO: Implement some weak caching of proxy classes and instances - // TODO: Make the proxy classes serializable... - - private DuckType() {} - - public static boolean instanceOf(Class pInterface, Object pObject) { - return instanceOf(new Class[] {pInterface}, new Object[] {pObject}); - } - - public static boolean instanceOf(Class[] pInterfaces, Object pObject) { - return instanceOf(pInterfaces, new Object[] {pObject}); - } - - public static boolean instanceOf(final Class[] pInterfaces, final Object[] pObjects) { - // Get all methods of all Class in pInterfaces, and see if pObjects has - // matching implementations - - // TODO: Possible optimization: If any of the interfaces are implemented - // by one of the objects' classes, we don't need to find every method... - - for (int i = 0; i < pInterfaces.length; i++) { - Class interfce = pInterfaces[i]; - - Method[] methods = interfce.getMethods(); - - for (int j = 0; j < methods.length; j++) { - Method method = methods[j]; - - //if (findMethodImplementation(method, getClasses(pObjects)) < 0) { - //if (findMethodImplementation(method, getClasses(pObjects)) == null) { - if (findMethodImplementation(method, pObjects) == null) { - return false; - } - } - } - - return true; - } - - // TODO: Might be moved to ReflectUtil - private static Class[] getClasses(final Object[] pObjects) { - Class[] classes = new Class[pObjects.length]; - - for (int i = 0; i < pObjects.length; i++) { - classes[i] = pObjects[i].getClass(); - } - - return classes; - } - - /** - * Searches for a class that has a method maching the given signature. - * Returns the index of the class in the {@code pClasses} array that has a - * matching method. - * If there is more than one class that has a matching method the first - * index will be returned. - * If there is no match in any of the classes, {@code -1} is returned. - * - * @param pMethod - * @param pObjects - * - * @return the first index of the object in the {@code pObjects} array that - * has a matching method, or {@code -1} if none was found. - */ - // TODO: Might be moved to ReflectUtil - //static int findMethodImplementation(final Method pMethod, final Class[] pClasses) { - static MethodProxy findMethodImplementation(final Method pMethod, final Object[] pObjects) { - // TODO: Optimization: Each getParameterTypes() invokation creates a - // new clone of the array. If we do it once and store the refs, that - // would be a good idea - - // Optimization, don't test class more than once - Set tested = new HashSet(pObjects.length); - - for (int i = 0; i < pObjects.length; i++) { - Class cls = pObjects[i].getClass(); - - if (tested.contains(cls)) { - continue; - } - else { - tested.add(cls); - } - - try { - // NOTE: This test might be too restrictive - // We could actually go ahead with - // supertype parameters or subtype return types... - // However, we should only do that after we have tried all - // classes for direct mathces. - Method method = cls.getMethod(pMethod.getName(), - pMethod.getParameterTypes()); - - if (matches(pMethod, method)) { - //return i; - // TODO: This is a waste of time if we are only testing if there's a method here... - return new MethodProxy(method, pObjects[i]); - } - } - catch (NoSuchMethodException e) { - // Ingore - } - } - - if (hasSuperTypes(pMethod.getParameterTypes())) { - SortedSet uniqueMethods = new TreeSet(); - for (int i = 0; i < pObjects.length; i++) { - Class cls = pObjects[i].getClass(); - - Method[] methods = cls.getMethods(); - - for (int j = 0; j < methods.length; j++) { - Method method = methods[j]; - - // Now, for each method - // 1 test if the name matches - // 2 test if the parameter types match for superclass - // 3 Test return types for assignability? - if (pMethod.getName().equals(method.getName()) - && isAssignableFrom(method.getParameterTypes(), pMethod.getParameterTypes()) - && pMethod.getReturnType().isAssignableFrom(method.getReturnType())) { - // 4 TODO: How to find the most specific match?! - //return new MethodProxy(method, pObjects[i]); - uniqueMethods.add(new MethodProxy(method, pObjects[i])); - } - } - } - if (uniqueMethods.size() == 1) { - return (MethodProxy) uniqueMethods.first(); - } - else { - // TODO: We need to figure out what method is the best match.. - } - } - - //return -1; - return null; - } - - private static boolean isAssignableFrom(Class[] pTypes, Class[] pSubTypes) { - if (pTypes.length != pSubTypes.length) { - return false; - } - - for (int i = 0; i < pTypes.length; i++) { - if (!pTypes[i].isAssignableFrom(pSubTypes[i])) { - return false; - } - - } - return true; - } - - private static boolean hasSuperTypes(Class[] pParameterTypes) { - for (int i = 0; i < pParameterTypes.length; i++) { - Class type = pParameterTypes[i]; - - if (type != Object.class - && (type.isInterface() || type.getSuperclass() != null)) { - return true; - } - } - return false; - } - - /** - * Tests two {@code Method}s for match. - * That is, they have same name and equal parameters. - * - * @param pLeft - * @param pRight - * - * @return - * - * @see Method#equals(Object) - */ - private static boolean matches(Method pLeft, Method pRight) { - if (pLeft == pRight) { - return true; - } - else if (pLeft.getName().equals(pRight.getName()) - && pLeft.getReturnType().isAssignableFrom(pRight.getReturnType())) { - - // Avoid unnecessary cloning - Class[] params1 = pLeft.getParameterTypes(); - Class[] params2 = pRight.getParameterTypes(); - if (params1.length == params2.length) { - for (int i = 0; i < params1.length; i++) { - if (params1[i] != params2[i]) { - return false; - } - } - return true; - } - } - - return false; - } - - public static Object implement(Class pInterface, Object pObject) throws NoMatchingMethodException { - return implement(new Class[] {pInterface}, new Object[] {pObject}, false); - } - - public static Object implement(Class[] pInterfaces, Object pObject) throws NoMatchingMethodException { - return implement(pInterfaces, new Object[] {pObject}, false); - } - - // TODO: What about the interfaces pObjects allready implements? - // TODO: Use first object as "identity"? Allow user to supply "indentity" - // that is not exposed as part of the implemented interfaces? - public static Object implement(final Class[] pInterfaces, final Object[] pObjects) throws NoMatchingMethodException { - return implement(pInterfaces, pObjects, false); - } - - public static Object implement(final Class[] pInterfaces, final Object[] pObjects, boolean pStubAbstract) throws NoMatchingMethodException { - Map delegates = new HashMap(pObjects.length * 10); - - for (int i = 0; i < pInterfaces.length; i++) { - Class interfce = pInterfaces[i]; - - Method[] methods = interfce.getMethods(); - - for (int j = 0; j < methods.length; j++) { - Method method = methods[j]; - - //int idx = findMethodImplementation(method, getClasses(pObjects)); - //Method impl = findMethodImplementation(method, getClasses(pObjects)); - MethodProxy impl = findMethodImplementation(method, pObjects); - //if (idx < 0) { - if (impl == null) { - // TODO: Maybe optionally create stubs that fails when invoked?! - if (pStubAbstract) { - impl = MethodProxy.createAbstract(method); - } - else { - throw new NoMatchingMethodException(interfce.getName() + "." - + method.getName() - + parameterTypesToString(method.getParameterTypes())); - } - } - - if (!delegates.containsKey(method)) { - // TODO: Must find the correct object... - //delegates.put(method, new MethodProxy(method, pObjects[idx])); - delegates.put(method, impl); - } - } - } - - // TODO: It's probably not good enough to use the current context class loader - // TODO: Either let user specify classloader directly - // TODO: ...or use one of the classloaders from pInterfaces or pObjects - return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), - pInterfaces, new DelegationHandler(delegates)); - } - - private static String parameterTypesToString(Class[] pTypes) { - StringBuilder buf = new StringBuilder(); - buf.append("("); - if (pTypes != null) { - for (int i = 0; i < pTypes.length; i++) { - if (i > 0) { - buf.append(", "); - } - Class c = pTypes[i]; - buf.append((c == null) ? "null" : c.getName()); - } - } - buf.append(")"); - return buf.toString(); - } - - static class MethodProxy { - private final Method mMethod; - private final Object mDelegate; - - private final static Object ABSTRACT_METHOD_DELEGATE = new Object() { - }; - - public static MethodProxy createAbstract(Method pMethod) { - return new MethodProxy(pMethod, ABSTRACT_METHOD_DELEGATE) { - public Object invoke(Object[] pArguments) throws Throwable { - throw abstractMehthodError(); - } - }; - } - - public MethodProxy(Method pMethod, Object pDelegate) { - if (pMethod == null) { - throw new IllegalArgumentException("method == null"); - } - if (pDelegate == null) { - throw new IllegalArgumentException("delegate == null"); - } - - mMethod = pMethod; - mDelegate = pDelegate; - } - - public Object invoke(Object[] pArguments) throws Throwable { - try { - return mMethod.invoke(mDelegate, pArguments); - } - catch (IllegalAccessException e) { - throw new Error(e); // This is an error in the impl - } - catch (InvocationTargetException e) { - throw e.getCause(); - } - } - - Error abstractMehthodError() { - return new AbstractMethodError(mMethod.toString()); - } - - public int hashCode() { - return mMethod.hashCode() ^ mDelegate.hashCode(); - } - - public boolean equals(Object pOther) { - if (pOther == this) { - return true; - } - if (pOther instanceof MethodProxy) { - MethodProxy other = (MethodProxy) pOther; - return mMethod.equals(other.mMethod) && mDelegate.equals(other.mDelegate); - } - return false; - } - - public String toString() { - return mMethod.toString() + mDelegate.toString(); - } - } - - public static class NoMatchingMethodException extends IllegalArgumentException { - public NoMatchingMethodException() { - super(); - } - - public NoMatchingMethodException(String s) { - super(s); - } - - public NoMatchingMethodException(Exception e) { - super(e.getMessage()); - initCause(e); - } - } - - // TODO: Must handle identity... - // TODO: equals/hashCode - // TODO: Allow clients to pass in Identity subclasses? - private static class DelegationHandler implements InvocationHandler { - private final Map mDelegates; - - public DelegationHandler(Map pDelegates) { - mDelegates = pDelegates; - } - - public final Object invoke(Object pProxy, Method pMethod, Object[] pArguments) - throws Throwable - { - if (pMethod.getDeclaringClass() == Object.class) { - // Intercept equals/hashCode/toString - String name = pMethod.getName(); - if (name.equals("equals")) { - return proxyEquals(pProxy, pArguments[0]); - } - else if (name.equals("hashCode")) { - return proxyHashCode(pProxy); - } - else if (name.equals("toString")) { - return proxyToString(pProxy); - } - - // Other methods are handled by their default Object - // implementations - return pMethod.invoke(this, pArguments); - } - - MethodProxy mp = (MethodProxy) mDelegates.get(pMethod); - - return mp.invoke(pArguments); - } - - protected Integer proxyHashCode(Object pProxy) { - //return new Integer(System.identityHashCode(pProxy)); - return new Integer(mDelegates.hashCode()); - } - - protected Boolean proxyEquals(Object pProxy, Object pOther) { - return pProxy == pOther || - (Proxy.isProxyClass(pOther.getClass()) - && Proxy.getInvocationHandler(pOther) instanceof DelegationHandler - && ((DelegationHandler) Proxy.getInvocationHandler(pOther)).mDelegates.equals(mDelegates)) - ? Boolean.TRUE : Boolean.FALSE; - } - - protected String proxyToString(Object pProxy) { - return pProxy.getClass().getName() + '@' + - Integer.toHexString(pProxy.hashCode()); - } - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/lang/ExceptionUtil.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/lang/ExceptionUtil.java deleted file mode 100755 index 9d1f89cf..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/lang/ExceptionUtil.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.twelvemonkeys.lang; - -import java.lang.reflect.UndeclaredThrowableException; - -import static com.twelvemonkeys.lang.Validate.notNull; - -/** - * ExceptionUtil - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/lang/ExceptionUtil.java#2 $ - */ -public final class ExceptionUtil { - - /** - * Re-throws an exception, either as-is if the exception was already unchecked, otherwise wrapped in - * a {@link RuntimeException} subtype. - * "Expected" exception types are wrapped in {@link RuntimeException}s directly, while - * "unexpected" exception types are wrapped in {@link java.lang.reflect.UndeclaredThrowableException}s. - * - * @param pThrowable the exception to launder - * @param pExpectedTypes the types of exception the code is expected to throw - */ - /*public*/ static void launder(final Throwable pThrowable, Class... pExpectedTypes) { - if (pThrowable instanceof Error) { - throw (Error) pThrowable; - } - if (pThrowable instanceof RuntimeException) { - throw (RuntimeException) pThrowable; - } - - for (Class expectedType : pExpectedTypes) { - if (expectedType.isInstance(pThrowable)) { - throw new RuntimeException(pThrowable); - } - } - - throw new UndeclaredThrowableException(pThrowable); - } - - @SuppressWarnings({"unchecked", "UnusedDeclaration"}) - static void throwAs(final Class pType, final Throwable pThrowable) throws T { - throw (T) pThrowable; - } - - public static void throwUnchecked(final Throwable pThrowable) { - throwAs(RuntimeException.class, pThrowable); - } - - /*@SafeVarargs*/ - @SuppressWarnings({"unchecked", "varargs"}) - /*public*/ static void handle(final Throwable pThrowable, final ThrowableHandler... pHandlers) { - handleImpl(pThrowable, (ThrowableHandler[]) pHandlers); - } - - private static void handleImpl(final Throwable pThrowable, final ThrowableHandler... pHandlers) { - // TODO: Sort more specific throwable handlers before less specific? - for (ThrowableHandler handler : pHandlers) { - if (handler.handles(pThrowable)) { - handler.handle(pThrowable); - return; - } - } - - // Not handled, re-throw - throwUnchecked(pThrowable); - } - - public static abstract class ThrowableHandler { - private final Class[] throwables; - - protected ThrowableHandler(final Class... pThrowables) { - throwables = notNull(pThrowables).clone(); - } - - final public boolean handles(final Throwable pThrowable) { - for (Class throwable : throwables) { - if (throwable.isAssignableFrom(pThrowable.getClass())) { - return true; - } - } - - return false; - } - - public abstract void handle(T pThrowable); - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/lang/MathUtil.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/lang/MathUtil.java deleted file mode 100755 index 5432d151..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/lang/MathUtil.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.lang; - -/** - * The class MathUtil contains methods for performing basic numeric operations - * such as the elementary exponential, logarithm, square root, and - * trigonometric functions. - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/lang/MathUtil.java#1 $ - */ -public final class MathUtil { - - /** */ - private MathUtil() { - } - - /** - * Returns the natural logarithm (base e) of a double value. - * Equivalent to {@code java.lang.Math.log}, just with a proper name. - * - * @param pArg a number greater than 0.0. - * @return the value ln {@code pArg}, the natural logarithm of - * {@code pArg}. - * - * @see java.lang.Math#log(double) - */ - public static double ln(final double pArg) { - return Math.log(pArg); - } - - /** - * Returns the base 10 logarithm of a double value. - * - * @param pArg a number greater than 0.0. - * @return the value log {@code pArg}, the base 10 logarithm of - * {@code pArg}. - */ - public static double log(final double pArg) { - return Math.log10(pArg); - } - - private final static double LN_2 = Math.log(2); - - /** - * Returns the base 2 logarithm of a double value. - * - * @param pArg a number greater than 0.0. - * @return the value log2 {@code pArg}, the base 2 - * logarithm of {@code pArg}. - */ - public static double log2(final double pArg) { - return Math.log(pArg) / LN_2; - } - - /** - * Returns the base N logarithm of a double value, for a given base - * N. - * - * @param pArg a number greater than 0.0. - * @param pBase a number greater than 0.0. - * - * @return the value logpBase {@code pArg}, the base - * {@code pBase} logarithm of {@code pArg}. - */ - public static double log(final double pArg, final double pBase) { - return Math.log(pArg) / Math.log(pBase); - } - - /** - * A replacement for {@code Math.abs}, that never returns negative values. - * {@code Math.abs(long)} does this for {@code Long.MIN_VALUE}. - * - * @see Math#abs(long) - * @see Long#MIN_VALUE - * - * @param pNumber a number - * @return the absolute value of {@code pNumber} - * - * @throws ArithmeticException if {@code pNumber == Long.MIN_VALUE} - */ - public static long abs(final long pNumber) { - if (pNumber == Long.MIN_VALUE) { - throw new ArithmeticException("long overflow: 9223372036854775808"); - } - - return (pNumber < 0) ? -pNumber : pNumber; - } - - /** - * A replacement for {@code Math.abs}, that never returns negative values. - * {@code Math.abs(int)} does this for {@code Integer.MIN_VALUE}. - * - * @see Math#abs(int) - * @see Integer#MIN_VALUE - * - * @param pNumber a number - * @return the absolute value of {@code pNumber} - * - * @throws ArithmeticException if {@code pNumber == Integer.MIN_VALUE} - */ - public static int abs(final int pNumber) { - if (pNumber == Integer.MIN_VALUE) { - throw new ArithmeticException("int overflow: 2147483648"); - } - - return (pNumber < 0) ? -pNumber : pNumber; - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/lang/MostUnfortunateException.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/lang/MostUnfortunateException.java deleted file mode 100755 index 120f1ff1..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/lang/MostUnfortunateException.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.lang; - -/** - * MostUnfortunateException - *

- * - * @author Harald Kuhr - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/lang/MostUnfortunateException.java#1 $ - */ -class MostUnfortunateException extends RuntimeException { - public MostUnfortunateException() { - this("Most unfortunate."); - } - - public MostUnfortunateException(Throwable pCause) { - this(pCause.getMessage(), pCause); - } - - public MostUnfortunateException(String pMessage, Throwable pCause) { - this(pMessage); - initCause(pCause); - } - - public MostUnfortunateException(String pMessage) { - super("A most unfortunate exception has occured: " + pMessage); - } -} \ No newline at end of file diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/lang/NativeLoader.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/lang/NativeLoader.java deleted file mode 100755 index 6d097cfa..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/lang/NativeLoader.java +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.lang; - -import com.twelvemonkeys.io.FileUtil; -import com.twelvemonkeys.util.FilterIterator; -import com.twelvemonkeys.util.service.ServiceRegistry; - -import java.io.*; -import java.util.Collections; -import java.util.Iterator; - -/** - * NativeLoader - *

- * - * @author Harald Kuhr - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/lang/NativeLoader.java#2 $ - */ -final class NativeLoader { - // TODO: Considerations: - // - Rename all libs like the current code, to .(so|dll|dylib)? - // - Keep library filename from jar, and rather store a separate - // properties-file with the library->library-file mappings? - // - As all invocations are with library file name, we could probably skip - // both renaming and properties-file altogether... - - // TODO: The real trick here, is how to load the correct library for the - // current platform... - // - Change String pResource to String[] pResources? - // - NativeResource class, that has a list of multiple resources? - // NativeResource(Map) os->native lib mapping - - // TODO: Consider exposing the method from SystemUtil - - // TODO: How about a SPI based solution?! - // public interface com.twelvemonkeys.lang.NativeResourceProvider - // - // imlementations return a pointer to the correct resource for a given (by - // this class) OS. - // - // String getResourceName(...) - // - // See http://tolstoy.com/samizdat/sysprops.html - // System properties: - // "os.name" - // Windows, Linux, Solaris/SunOS, - // Mac OS/Mac OS X/Rhapsody (aka Mac OS X Server) - // General Unix (AIX, Digital Unix, FreeBSD, HP-UX, Irix) - // OS/2 - // "os.arch" - // Windows: x86 - // Linux: x86, i386, i686, x86_64, ia64, - // Solaris: sparc, sparcv9, x86 - // Mac OS: PowerPC, ppc, i386 - // AIX: x86, ppc - // Digital Unix: alpha - // FreeBSD: x86, sparc - // HP-UX: PA-RISC - // Irix: mips - // OS/2: x86 - // "os.version" - // Windows: 4.0 -> NT/95, 5.0 -> 2000, 5.1 -> XP (don't care about old versions, CE etc) - // Mac OS: 8.0, 8.1, 10.0 -> OS X, 10.x.x -> OS X, 5.6 -> Rhapsody (!) - // - // Normalize os.name, os.arch and os.version?! - - - ///** Normalized operating system constant */ - //static final OperatingSystem OS_NAME = normalizeOperatingSystem(); - // - ///** Normalized system architecture constant */ - //static final Architecture OS_ARCHITECTURE = normalizeArchitecture(); - // - ///** Unormalized operating system version constant (for completeness) */ - //static final String OS_VERSION = System.getProperty("os.version"); - - static final NativeResourceRegistry sRegistry = new NativeResourceRegistry(); - - private NativeLoader() { - } - -/* - private static Architecture normalizeArchitecture() { - String arch = System.getProperty("os.arch"); - if (arch == null) { - throw new IllegalStateException("System property \"os.arch\" == null"); - } - - arch = arch.toLowerCase(); - if (OS_NAME == OperatingSystem.Windows - && (arch.startsWith("x86") || arch.startsWith("i386"))) { - return Architecture.X86; - // TODO: 64 bit - } - else if (OS_NAME == OperatingSystem.Linux) { - if (arch.startsWith("x86") || arch.startsWith("i386")) { - return Architecture.I386; - } - else if (arch.startsWith("i686")) { - return Architecture.I686; - } - // TODO: More Linux options? - // TODO: 64 bit - } - else if (OS_NAME == OperatingSystem.MacOS) { - if (arch.startsWith("power") || arch.startsWith("ppc")) { - return Architecture.PPC; - } - else if (arch.startsWith("i386")) { - return Architecture.I386; - } - } - else if (OS_NAME == OperatingSystem.Solaris) { - if (arch.startsWith("sparc")) { - return Architecture.SPARC; - } - if (arch.startsWith("x86")) { - // TODO: Should we use i386 as Linux and Mac does? - return Architecture.X86; - } - // TODO: 64 bit - } - - return Architecture.Unknown; - } -*/ - -/* - private static OperatingSystem normalizeOperatingSystem() { - String os = System.getProperty("os.name"); - if (os == null) { - throw new IllegalStateException("System property \"os.name\" == null"); - } - - os = os.toLowerCase(); - if (os.startsWith("windows")) { - return OperatingSystem.Windows; - } - else if (os.startsWith("linux")) { - return OperatingSystem.Linux; - } - else if (os.startsWith("mac os")) { - return OperatingSystem.MacOS; - } - else if (os.startsWith("solaris") || os.startsWith("sunos")) { - return OperatingSystem.Solaris; - } - - return OperatingSystem.Unknown; - } -*/ - - // TODO: We could actually have more than one resource for each lib... - private static String getResourceFor(String pLibrary) { - Iterator providers = sRegistry.providers(pLibrary); - while (providers.hasNext()) { - NativeResourceSPI resourceSPI = providers.next(); - - try { - return resourceSPI.getClassPathResource(Platform.get()); - } - catch (Throwable t) { - // Dergister and try next - sRegistry.deregister(resourceSPI); - } - } - - return null; - } - - /** - * Loads a native library. - * - * @param pLibrary name of the library - * - * @throws UnsatisfiedLinkError - */ - public static void loadLibrary(String pLibrary) { - loadLibrary0(pLibrary, null, null); - } - - /** - * Loads a native library. - * - * @param pLibrary name of the library - * @param pLoader the class loader to use - * - * @throws UnsatisfiedLinkError - */ - public static void loadLibrary(String pLibrary, ClassLoader pLoader) { - loadLibrary0(pLibrary, null, pLoader); - } - - /** - * Loads a native library. - * - * @param pLibrary name of the library - * @param pResource name of the resource - * @param pLoader the class loader to use - * - * @throws UnsatisfiedLinkError - */ - static void loadLibrary0(String pLibrary, String pResource, ClassLoader pLoader) { - if (pLibrary == null) { - throw new IllegalArgumentException("library == null"); - } - - // Try loading normal way - UnsatisfiedLinkError unsatisfied; - try { - System.loadLibrary(pLibrary); - return; - } - catch (UnsatisfiedLinkError err) { - // Ignore - unsatisfied = err; - } - - final ClassLoader loader = pLoader != null ? pLoader : Thread.currentThread().getContextClassLoader(); - final String resource = pResource != null ? pResource : getResourceFor(pLibrary); - - // TODO: resource may be null, and that MIGHT be okay, IFF the resource - // is allready unpacked to the user dir... However, we then need another - // way to resolve the library extension... - // Right now we just fail in a predictable way (no NPE)! - if (resource == null) { - throw unsatisfied; - } - - // Default to load/store from user.home - File dir = new File(System.getProperty("user.home") + "/.twelvemonkeys/lib"); - dir.mkdirs(); - //File libraryFile = new File(dir.getAbsolutePath(), pLibrary + LIBRARY_EXTENSION); - File libraryFile = new File(dir.getAbsolutePath(), pLibrary + "." + FileUtil.getExtension(resource)); - - if (!libraryFile.exists()) { - try { - extractToUserDir(resource, libraryFile, loader); - } - catch (IOException ioe) { - UnsatisfiedLinkError err = new UnsatisfiedLinkError("Unable to extract resource to dir: " + libraryFile.getAbsolutePath()); - err.initCause(ioe); - throw err; - } - } - - // Try to load the library from the file we just wrote - System.load(libraryFile.getAbsolutePath()); - } - - private static void extractToUserDir(String pResource, File pLibraryFile, ClassLoader pLoader) throws IOException { - // Get resource from classpath - InputStream in = pLoader.getResourceAsStream(pResource); - if (in == null) { - throw new FileNotFoundException("Unable to locate classpath resource: " + pResource); - } - - // Write to file in user dir - FileOutputStream fileOut = null; - try { - fileOut = new FileOutputStream(pLibraryFile); - - byte[] tmp = new byte[1024]; - // copy the contents of our resource out to the destination - // dir 1K at a time. 1K may seem arbitrary at first, but today - // is a Tuesday, so it makes perfect sense. - int bytesRead = in.read(tmp); - while (bytesRead != -1) { - fileOut.write(tmp, 0, bytesRead); - bytesRead = in.read(tmp); - } - } - finally { - FileUtil.close(fileOut); - FileUtil.close(in); - } - } - - // TODO: Validate OS names? - // Windows - // Linux - // Solaris - // Mac OS (OSX+) - // Generic Unix? - // Others? - - // TODO: OSes that support different architectures might require different - // resources for each architecture.. Need a namespace/flavour system - // TODO: 32 bit/64 bit issues? - // Eg: Windows, Windows/32, Windows/64, Windows/Intel/64? - // Solaris/Sparc, Solaris/Intel/64 - // MacOS/PowerPC, MacOS/Intel - /* - public static class NativeResource { - private Map mMap; - - public NativeResource(String[] pOSNames, String[] pReourceNames) { - if (pOSNames == null) { - throw new IllegalArgumentException("osNames == null"); - } - if (pReourceNames == null) { - throw new IllegalArgumentException("resourceNames == null"); - } - if (pOSNames.length != pReourceNames.length) { - throw new IllegalArgumentException("osNames.length != resourceNames.length"); - } - - Map map = new HashMap(); - for (int i = 0; i < pOSNames.length; i++) { - map.put(pOSNames[i], pReourceNames[i]); - } - - mMap = Collections.unmodifiableMap(map); - } - - public NativeResource(Map pMap) { - if (pMap == null) { - throw new IllegalArgumentException("map == null"); - } - - Map map = new HashMap(pMap); - - Iterator it = map.keySet().iterator(); - while (it.hasNext()) { - Map.Entry entry = (Map.Entry) it.next(); - if (!(entry.getKey() instanceof String && entry.getValue() instanceof String)) { - throw new IllegalArgumentException("map contains non-string entries: " + entry); - } - } - - mMap = Collections.unmodifiableMap(map); - } - - protected NativeResource() { - } - - public final String resourceForCurrentOS() { - throw new UnsupportedOperationException(); - } - - protected String getResourceName(String pOSName) { - return (String) mMap.get(pOSName); - } - } - */ - - private static class NativeResourceRegistry extends ServiceRegistry { - public NativeResourceRegistry() { - super(Collections.singletonList(NativeResourceSPI.class).iterator()); - registerApplicationClasspathSPIs(); - } - - Iterator providers(final String nativeResource) { - return new FilterIterator( - providers(NativeResourceSPI.class), - new NameFilter(nativeResource) - ); - } - } - - private static class NameFilter implements FilterIterator.Filter { - private final String name; - - NameFilter(String pName) { - if (pName == null) { - throw new IllegalArgumentException("name == null"); - } - name = pName; - } - public boolean accept(NativeResourceSPI pElement) { - return name.equals(pElement.getResourceName()); - } - } -} \ No newline at end of file diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/lang/NativeResourceSPI.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/lang/NativeResourceSPI.java deleted file mode 100755 index 2290ef2a..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/lang/NativeResourceSPI.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.lang; - -/** - * Abstract base class for native reource providers to iplement. - *

- * - * @author Harald Kuhr - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/lang/NativeResourceSPI.java#1 $ - */ -public abstract class NativeResourceSPI { - - private final String mResourceName; - - /** - * Creates a {@code NativeResourceSPI} with the given name. - * - * The name will typically be a short string, with the common name of the - * library that is provided, like "JMagick", "JOGL" or similar. - * - * @param pResourceName name of the resource (native library) provided by - * this SPI. - * - * @throws IllegalArgumentException if {@code pResourceName == null} - */ - protected NativeResourceSPI(String pResourceName) { - if (pResourceName == null) { - throw new IllegalArgumentException("resourceName == null"); - } - - mResourceName = pResourceName; - } - - /** - * Returns the name of the resource (native library) provided by this SPI. - * - * The name will typically be a short string, with the common name of the - * library that is provided, like "JMagick", "JOGL" or similar. - *

- * NOTE: This method is intended for the SPI framework, and should not be - * invoked by client code. - * - * @return the name of the resource provided by this SPI - */ - public final String getResourceName() { - return mResourceName; - } - - /** - * Returns the path to the classpath resource that is suited for the given - * runtime configuration. - *

- * In the common case, the {@code pPlatform} parameter is - * normalized from the values found in - * {@code System.getProperty("os.name")} and - * {@code System.getProperty("os.arch")}. - * For unknown operating systems and architectures, {@code toString()} on - * the platforms's properties will return the the same value as these properties. - *

- * NOTE: This method is intended for the SPI framework, and should not be - * invoked by client code. - * - * @param pPlatform the current platform - * @return a {@code String} containing the path to a classpath resource or - * {@code null} if no resource is available. - * - * @see com.twelvemonkeys.lang.Platform.OperatingSystem - * @see com.twelvemonkeys.lang.Platform.Architecture - * @see System#getProperties() - */ - public abstract String getClassPathResource(final Platform pPlatform); -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/net/AuthenticatorFilter.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/net/AuthenticatorFilter.java deleted file mode 100755 index 21171d22..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/net/AuthenticatorFilter.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.net; - -import java.net.*; - -/** - * Interface for filtering Authenticator requests, used by the - * SimpleAuthenticator. - * - * @see SimpleAuthenticator - * @see java.net.Authenticator - * - * @author Harald Kuhr - * @version 1.0 - */ -public interface AuthenticatorFilter { - public boolean accept(InetAddress pAddress, int pPort, String pProtocol, String pPrompt, String pScheme); -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/net/BASE64.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/net/BASE64.java deleted file mode 100755 index 4d4346f8..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/net/BASE64.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.net; - -import com.twelvemonkeys.io.*; -import com.twelvemonkeys.io.enc.Base64Decoder; -import com.twelvemonkeys.io.enc.DecoderStream; - -import java.io.*; - - -/** - * This class does BASE64 encoding (and decoding). - * - * @author unascribed - * @author last modified by $Author: haku $ - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/BASE64.java#1 $ - * @deprecated Use {@link com.twelvemonkeys.io.enc.Base64Encoder}/{@link Base64Decoder} instead - */ -class BASE64 { - /** - * This array maps the characters to their 6 bit values - */ - private final static char[] PEM_ARRAY = { - //0 1 2 3 4 5 6 7 - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 0 - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 1 - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 2 - 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', // 3 - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 4 - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', // 5 - 'w', 'x', 'y', 'z', '0', '1', '2', '3', // 6 - '4', '5', '6', '7', '8', '9', '+', '/' // 7 - }; - - /** - * Encodes the input data using the standard base64 encoding scheme. - * - * @param pData the bytes to encode to base64 - * @return a string with base64 encoded data - */ - public static String encode(byte[] pData) { - int offset = 0; - int len; - StringBuilder buf = new StringBuilder(); - - while ((pData.length - offset) > 0) { - byte a, b, c; - if ((pData.length - offset) > 2) { - len = 3; - } - else { - len = pData.length - offset; - } - - switch (len) { - case 1: - a = pData[offset]; - b = 0; - buf.append(PEM_ARRAY[(a >>> 2) & 0x3F]); - buf.append(PEM_ARRAY[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]); - buf.append('='); - buf.append('='); - offset++; - break; - case 2: - a = pData[offset]; - b = pData[offset + 1]; - c = 0; - buf.append(PEM_ARRAY[(a >>> 2) & 0x3F]); - buf.append(PEM_ARRAY[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]); - buf.append(PEM_ARRAY[((b << 2) & 0x3c) + ((c >>> 6) & 0x3)]); - buf.append('='); - offset += offset + 2; // ??? - break; - default: - a = pData[offset]; - b = pData[offset + 1]; - c = pData[offset + 2]; - buf.append(PEM_ARRAY[(a >>> 2) & 0x3F]); - buf.append(PEM_ARRAY[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]); - buf.append(PEM_ARRAY[((b << 2) & 0x3c) + ((c >>> 6) & 0x3)]); - buf.append(PEM_ARRAY[c & 0x3F]); - offset = offset + 3; - break; - } - - } - return buf.toString(); - } - - public static byte[] decode(String pData) throws IOException { - InputStream in = new DecoderStream(new ByteArrayInputStream(pData.getBytes()), new Base64Decoder()); - ByteArrayOutputStream bytes = new FastByteArrayOutputStream(pData.length() * 3); - FileUtil.copy(in, bytes); - - return bytes.toByteArray(); - } - - //private final static sun.misc.BASE64Decoder DECODER = new sun.misc.BASE64Decoder(); - - public static void main(String[] pArgs) throws IOException { - if (pArgs.length == 1) { - System.out.println(encode(pArgs[0].getBytes())); - } - else - if (pArgs.length == 2 && ("-d".equals(pArgs[0]) || "--decode".equals(pArgs[0]))) - { - System.out.println(new String(decode(pArgs[1]))); - } - else { - System.err.println("BASE64 [ -d | --decode ] arg"); - System.err.println("Encodes or decodes a given string"); - System.exit(5); - } - } -} \ No newline at end of file diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/net/HttpURLConnection.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/net/HttpURLConnection.java deleted file mode 100755 index 62119c2b..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/net/HttpURLConnection.java +++ /dev/null @@ -1,1101 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.net; - -import com.twelvemonkeys.lang.StringUtil; - -import java.io.*; -import java.net.*; -import java.util.*; - -/** - * A URLConnection with support for HTTP-specific features. See - * the spec for details. - * This version also supports read and connect timeouts, making it more useful - * for clients with limitted time. - *

- * Note that the timeouts are created on the socket level, and that - *

- * Note: This class should now work as expected, but it needs more testing before - * it can enter production release. - *
- * --.k - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/net/HttpURLConnection.java#1 $ - * @todo Write JUnit TestCase - * @todo ConnectionMananger! - * @see RFC 2616 - */ -public class HttpURLConnection extends java.net.HttpURLConnection { - /** - * HTTP Status-Code 307: Temporary Redirect - */ - public final static int HTTP_REDIRECT = 307; - private final static int HTTP_DEFAULT_PORT = 80; - private final static String HTTP_HEADER_END = "\r\n\r\n"; - private static final String HEADER_WWW_AUTH = "WWW-Authenticate"; - private final static int BUF_SIZE = 8192; - private int maxRedirects = (System.getProperty("http.maxRedirects") != null) - ? Integer.parseInt(System.getProperty("http.maxRedirects")) - : 20; - protected int timeout = -1; - protected int connectTimeout = -1; - private Socket socket = null; - protected InputStream errorStream = null; - protected InputStream inputStream = null; - protected OutputStream outputStream = null; - private String[] responseHeaders = null; - protected Properties responseHeaderFields = null; - protected Properties requestProperties = new Properties(); - - /** - * Creates a HttpURLConnection. - * - * @param pURL the URL to connect to. - */ - protected HttpURLConnection(URL pURL) { - this(pURL, 0, 0); - } - - /** - * Creates a HttpURLConnection with a given read and connect timeout. - * A timeout value of zero is interpreted as an - * infinite timeout. - * - * @param pURL the URL to connect to. - * @param pTimeout the maximum time the socket will block for read - * and connect operations. - */ - protected HttpURLConnection(URL pURL, int pTimeout) { - this(pURL, pTimeout, pTimeout); - } - - /** - * Creates a HttpURLConnection with a given read and connect timeout. - * A timeout value of zero is interpreted as an - * infinite timeout. - * - * @param pURL the URL to connect to. - * @param pTimeout the maximum time the socket will block for read - * operations. - * @param pConnectTimeout the maximum time the socket will block for - * connection. - */ - protected HttpURLConnection(URL pURL, int pTimeout, int pConnectTimeout) { - super(pURL); - setTimeout(pTimeout); - connectTimeout = pConnectTimeout; - } - - /** - * Sets the general request property. If a property with the key already - * exists, overwrite its value with the new value. - *

- *

NOTE: HTTP requires all request properties which can - * legally have multiple instances with the same key - * to use a comma-seperated list syntax which enables multiple - * properties to be appended into a single property. - * - * @param pKey the keyword by which the request is known - * (e.g., "{@code accept}"). - * @param pValue the value associated with it. - * @see #getRequestProperty(java.lang.String) - */ - public void setRequestProperty(String pKey, String pValue) { - if (connected) { - throw new IllegalAccessError("Already connected"); - } - String oldValue = requestProperties.getProperty(pKey); - - if (oldValue == null) { - requestProperties.setProperty(pKey, pValue); - } - else { - requestProperties.setProperty(pKey, oldValue + ", " + pValue); - } - } - - /** - * Returns the value of the named general request property for this - * connection. - * - * @param pKey the keyword by which the request is known (e.g., "accept"). - * @return the value of the named general request property for this - * connection. - * @see #setRequestProperty(java.lang.String, java.lang.String) - */ - public String getRequestProperty(String pKey) { - if (connected) { - throw new IllegalAccessError("Already connected"); - } - return requestProperties.getProperty(pKey); - } - - /** - * Gets HTTP response status from responses like: - *

-     * HTTP/1.0 200 OK
-     * HTTP/1.0 401 Unauthorized
-     * 
- * Extracts the ints 200 and 401 respectively. - * Returns -1 if none can be discerned - * from the response (i.e., the response is not valid HTTP). - *

- * - * - * @return the HTTP Status-Code - * @throws IOException if an error occurred connecting to the server. - */ - public int getResponseCode() throws IOException { - if (responseCode != -1) { - return responseCode; - } - - // Make sure we've gotten the headers - getInputStream(); - String resp = getHeaderField(0); - - // should have no leading/trailing LWS - // expedite the typical case by assuming it has the - // form "HTTP/1.x 2XX " - int ind; - - try { - ind = resp.indexOf(' '); - while (resp.charAt(ind) == ' ') { - ind++; - } - responseCode = Integer.parseInt(resp.substring(ind, ind + 3)); - responseMessage = resp.substring(ind + 4).trim(); - return responseCode; - } - catch (Exception e) { - return responseCode; - } - } - - /** - * Returns the name of the specified header field. - * - * @param pName the name of a header field. - * @return the value of the named header field, or {@code null} - * if there is no such field in the header. - */ - public String getHeaderField(String pName) { - return responseHeaderFields.getProperty(StringUtil.toLowerCase(pName)); - } - - /** - * Returns the value for the {@code n}th header field. - * It returns {@code null} if there are fewer than - * {@code n} fields. - *

- * This method can be used in conjunction with the - * {@code getHeaderFieldKey} method to iterate through all - * the headers in the message. - * - * @param pIndex an index. - * @return the value of the {@code n}th header field. - * @see java.net.URLConnection#getHeaderFieldKey(int) - */ - public String getHeaderField(int pIndex) { - // TODO: getInputStream() first, to make sure we have header fields - if (pIndex >= responseHeaders.length) { - return null; - } - String field = responseHeaders[pIndex]; - - // pIndex == 0, means the response code etc (i.e. "HTTP/1.1 200 OK"). - if ((pIndex == 0) || (field == null)) { - return field; - } - int idx = field.indexOf(':'); - - return ((idx > 0) - ? field.substring(idx).trim() - : ""); // TODO: "" or null? - } - - /** - * Returns the key for the {@code n}th header field. - * - * @param pIndex an index. - * @return the key for the {@code n}th header field, - * or {@code null} if there are fewer than {@code n} - * fields. - */ - public String getHeaderFieldKey(int pIndex) { - // TODO: getInputStream() first, to make sure we have header fields - if (pIndex >= responseHeaders.length) { - return null; - } - String field = responseHeaders[pIndex]; - - if (StringUtil.isEmpty(field)) { - return null; - } - int idx = field.indexOf(':'); - - return StringUtil.toLowerCase(((idx > 0) - ? field.substring(0, idx) - : field)); - } - - /** - * Sets the read timeout for the undelying socket. - * A timeout of zero is interpreted as an - * infinite timeout. - * - * @param pTimeout the maximum time the socket will block for read - * operations, in milliseconds. - */ - public void setTimeout(int pTimeout) { - if (pTimeout < 0) { // Must be positive - throw new IllegalArgumentException("Timeout must be positive."); - } - timeout = pTimeout; - if (socket != null) { - try { - socket.setSoTimeout(pTimeout); - } - catch (SocketException se) { - // Not much to do about that... - } - } - } - - /** - * Gets the read timeout for the undelying socket. - * - * @return the maximum time the socket will block for read operations, in - * milliseconds. - * The default value is zero, which is interpreted as an - * infinite timeout. - */ - public int getTimeout() { - - try { - return ((socket != null) - ? socket.getSoTimeout() - : timeout); - } - catch (SocketException se) { - return timeout; - } - } - - /** - * Returns an input stream that reads from this open connection. - * - * @return an input stream that reads from this open connection. - * @throws IOException if an I/O error occurs while - * creating the input stream. - */ - public synchronized InputStream getInputStream() throws IOException { - if (!connected) { - connect(); - } - - // Nothing to return - if (responseCode == HTTP_NOT_FOUND) { - throw new FileNotFoundException(url.toString()); - } - int length; - - if (inputStream == null) { - return null; - } - - // "De-chunk" the output stream - else if ("chunked".equalsIgnoreCase(getHeaderField("Transfer-Encoding"))) { - if (!(inputStream instanceof ChunkedInputStream)) { - inputStream = new ChunkedInputStream(inputStream); - } - } - - // Make sure we don't wait forever, if the content-length is known - else if ((length = getHeaderFieldInt("Content-Length", -1)) >= 0) { - if (!(inputStream instanceof FixedLengthInputStream)) { - inputStream = new FixedLengthInputStream(inputStream, length); - } - } - return inputStream; - } - - /** - * Returns an output stream that writes to this connection. - * - * @return an output stream that writes to this connection. - * @throws IOException if an I/O error occurs while - * creating the output stream. - */ - public synchronized OutputStream getOutputStream() throws IOException { - - if (!connected) { - connect(); - } - return outputStream; - } - - /** - * Indicates that other requests to the server - * are unlikely in the near future. Calling disconnect() - * should not imply that this HttpURLConnection - * instance can be reused for other requests. - */ - public void disconnect() { - if (socket != null) { - try { - socket.close(); - } - catch (IOException ioe) { - - // Does not matter, I guess. - } - socket = null; - } - connected = false; - } - - /** - * Internal connect method. - */ - private void connect(final URL pURL, PasswordAuthentication pAuth, String pAuthType, int pRetries) throws IOException { - // Find correct port - final int port = (pURL.getPort() > 0) - ? pURL.getPort() - : HTTP_DEFAULT_PORT; - - // Create socket if we don't have one - if (socket == null) { - //socket = new Socket(pURL.getHost(), port); // Blocks... - socket = createSocket(pURL, port, connectTimeout); - socket.setSoTimeout(timeout); - } - - // Get Socket output stream - OutputStream os = socket.getOutputStream(); - - // Connect using HTTP - writeRequestHeaders(os, pURL, method, requestProperties, usingProxy(), pAuth, pAuthType); - - // Get response input stream - InputStream sis = socket.getInputStream(); - BufferedInputStream is = new BufferedInputStream(sis); - - // Detatch reponse headers from reponse input stream - InputStream header = detatchResponseHeader(is); - - // Parse headers and set response code/message - responseHeaders = parseResponseHeader(header); - responseHeaderFields = parseHeaderFields(responseHeaders); - - //System.err.println("Headers fields:"); - //responseHeaderFields.list(System.err); - // Test HTTP response code, to see if further action is needed - switch (getResponseCode()) { - case HTTP_OK: - // 200 OK - inputStream = is; - errorStream = null; - break; - - /* - case HTTP_PROXY_AUTH: - // 407 Proxy Authentication Required - */ - case HTTP_UNAUTHORIZED: - // 401 Unauthorized - // Set authorization and try again.. Slightly more compatible - responseCode = -1; - - // IS THIS REDIRECTION?? - //if (instanceFollowRedirects) { ??? - String auth = getHeaderField(HEADER_WWW_AUTH); - - // Missing WWW-Authenticate header for 401 response is an error - if (StringUtil.isEmpty(auth)) { - throw new ProtocolException("Missing \"" + HEADER_WWW_AUTH + "\" header for response: 401 " + responseMessage); - } - - // Get real mehtod from WWW-Authenticate header - int SP = auth.indexOf(" "); - String method; - String realm = null; - - if (SP >= 0) { - method = auth.substring(0, SP); - if (auth.length() >= SP + 7) { - realm = auth.substring(SP + 7); // " realm=".lenght() == 7 - } - - // else no realm - } - else { - // Default mehtod is Basic - method = SimpleAuthenticator.BASIC; - } - - // Get PasswordAuthentication - PasswordAuthentication pa = Authenticator.requestPasswordAuthentication(NetUtil.createInetAddressFromURL(pURL), port, - pURL.getProtocol(), realm, method); - - // Avoid infinite loop - if (pRetries++ <= 0) { - throw new ProtocolException("Server redirected too many times (" + maxRedirects + ") (Authentication required: " + auth + ")"); // This is what sun.net.www.protocol.http.HttpURLConnection does - } - else if (pa != null) { - connect(pURL, pa, method, pRetries); - } - break; - case HTTP_MOVED_PERM: - // 301 Moved Permanently - case HTTP_MOVED_TEMP: - // 302 Found - case HTTP_SEE_OTHER: - // 303 See Other - /* - case HTTP_USE_PROXY: - // 305 Use Proxy - // How do we handle this? - */ - case HTTP_REDIRECT: - // 307 Temporary Redirect - //System.err.println("Redirecting " + getResponseCode()); - if (instanceFollowRedirects) { - // Redirect - responseCode = -1; // Because of the java.net.URLConnection - - // getResponseCode implementation... - // --- - // I think redirects must be get? - //setRequestMethod("GET"); - // --- - String location = getHeaderField("Location"); - URL newLoc = new URL(pURL, location); - - // Test if we can reuse the Socket - if (!(newLoc.getAuthority().equals(pURL.getAuthority()) && (newLoc.getPort() == pURL.getPort()))) { - socket.close(); // Close the socket, won't need it anymore - socket = null; - } - if (location != null) { - //System.err.println("Redirecting to " + location); - // Avoid infinite loop - if (--pRetries <= 0) { - throw new ProtocolException("Server redirected too many times (5)"); - } - else { - connect(newLoc, pAuth, pAuthType, pRetries); - } - } - break; - } - - // ...else, fall through default (if no Location: header) - default : - // Not 200 OK, or any of the redirect responses - // Probably an error... - errorStream = is; - inputStream = null; - } - - // --- Need rethinking... - // No further questions, let the Socket wait forever (until the server - // closes the connection) - //socket.setSoTimeout(0); - // Probably not... The timeout should only kick if the read BLOCKS. - // Shutdown output, meaning any writes to the outputstream below will - // probably fail... - //socket.shutdownOutput(); - // Not a good idea at all... POSTs need the outputstream to send the - // form-data. - // --- /Need rethinking. - outputStream = os; - } - - private static interface SocketConnector extends Runnable { - - /** - * Method getSocket - * - * @return the socket - * @throws IOException - */ - public Socket getSocket() throws IOException; - } - - /** - * Creates a socket to the given URL and port, with the given connect - * timeout. If the socket waits more than the given timout to connect, - * an ConnectException is thrown. - * - * @param pURL the URL to connect to - * @param pPort the port to connect to - * @param pConnectTimeout the connect timeout - * @return the created Socket. - * @throws ConnectException if the connection is refused or otherwise - * times out. - * @throws UnknownHostException if the IP address of the host could not be - * determined. - * @throws IOException if an I/O error occurs when creating the socket. - * @todo Move this code to a SocetImpl or similar? - * @see Socket#Socket(String,int) - */ - private Socket createSocket(final URL pURL, final int pPort, int pConnectTimeout) throws IOException { - Socket socket; - final Object current = this; - SocketConnector connector; - Thread t = new Thread(connector = new SocketConnector() { - - private IOException mConnectException = null; - private Socket mLocalSocket = null; - - public Socket getSocket() throws IOException { - - if (mConnectException != null) { - throw mConnectException; - } - return mLocalSocket; - } - - // Run method - public void run() { - - try { - mLocalSocket = new Socket(pURL.getHost(), pPort); // Blocks... - } - catch (IOException ioe) { - - // Store this exception for later - mConnectException = ioe; - } - - // Signal that we are done - synchronized (current) { - current.notify(); - } - } - }); - - t.start(); - - // Wait for connect - synchronized (this) { - try { - - /// Only wait if thread is alive! - if (t.isAlive()) { - if (pConnectTimeout > 0) { - wait(pConnectTimeout); - } - else { - wait(); - } - } - } - catch (InterruptedException ie) { - - // Continue excecution on interrupt? Hmmm.. - } - } - - // Throw exception if the socket didn't connect fast enough - if ((socket = connector.getSocket()) == null) { - throw new ConnectException("Socket connect timed out!"); - } - return socket; - } - - /** - * Opens a communications link to the resource referenced by this - * URL, if such a connection has not already been established. - *

- * If the {@code connect} method is called when the connection - * has already been opened (indicated by the {@code connected} - * field having the value {@code true}), the call is ignored. - *

- * URLConnection objects go through two phases: first they are - * created, then they are connected. After being created, and - * before being connected, various options can be specified - * (e.g., doInput and UseCaches). After connecting, it is an - * error to try to set them. Operations that depend on being - * connected, like getContentLength, will implicitly perform the - * connection, if necessary. - * - * @throws IOException if an I/O error occurs while opening the - * connection. - * @see java.net.URLConnection#connected - * @see RFC 2616 - */ - public void connect() throws IOException { - if (connected) { - return; // Ignore - } - connected = true; - connect(url, null, null, maxRedirects); - } - - /** - * TODO: Proxy support is still missing. - * - * @return this method returns false, as proxy suport is not implemented. - */ - public boolean usingProxy() { - return false; - } - - /** - * Writes the HTTP request headers, for HTTP GET method. - * - * @see RFC 2616 - */ - private static void writeRequestHeaders(OutputStream pOut, URL pURL, String pMethod, Properties pProps, boolean pUsingProxy, - PasswordAuthentication pAuth, String pAuthType) { - PrintWriter out = new PrintWriter(pOut, true); // autoFlush - - if (!pUsingProxy) { - out.println(pMethod + " " + (!StringUtil.isEmpty(pURL.getPath()) - ? pURL.getPath() - : "/") + ((pURL.getQuery() != null) - ? "?" + pURL.getQuery() - : "") + " HTTP/1.1"); // HTTP/1.1 - - // out.println("Connection: close"); // No persistent connections yet - - /* - System.err.println(pMethod + " " - + (!StringUtil.isEmpty(pURL.getPath()) ? pURL.getPath() : "/") - + (pURL.getQuery() != null ? "?" + pURL.getQuery() : "") - + " HTTP/1.1"); // HTTP/1.1 - */ - - // Authority (Host: HTTP/1.1 field, but seems to work for HTTP/1.0) - out.println("Host: " + pURL.getHost() + ((pURL.getPort() != -1) - ? ":" + pURL.getPort() - : "")); - - /* - System.err.println("Host: " + pURL.getHost() - + (pURL.getPort() != -1 ? ":" + pURL.getPort() : "")); - */ - } - else { - - ////-- PROXY (absolute) VERSION - out.println(pMethod + " " + pURL.getProtocol() + "://" + pURL.getHost() + ((pURL.getPort() != -1) - ? ":" + pURL.getPort() - : "") + pURL.getPath() + ((pURL.getQuery() != null) - ? "?" + pURL.getQuery() - : "") + " HTTP/1.1"); - } - - // Check if we have authentication - if (pAuth != null) { - - // If found, set Authorization header - byte[] userPass = (pAuth.getUserName() + ":" + new String(pAuth.getPassword())).getBytes(); - - // "Authorization" ":" credentials - out.println("Authorization: " + pAuthType + " " + BASE64.encode(userPass)); - - /* - System.err.println("Authorization: " + pAuthType + " " - + BASE64.encode(userPass)); - */ - } - - // Iterate over properties - - for (Map.Entry property : pProps.entrySet()) { - out.println(property.getKey() + ": " + property.getValue()); - - //System.err.println(property.getKey() + ": " + property.getValue()); - } - out.println(); // Empty line, marks end of request-header - } - - /** - * Finds the end of the HTTP response header in an array of bytes. - * - * @todo This one's a little dirty... - */ - private static int findEndOfHeader(byte[] pBytes, int pEnd) { - byte[] header = HTTP_HEADER_END.getBytes(); - - // Normal condition, check all bytes - for (int i = 0; i < pEnd - 4; i++) { // Need 4 bytes to match - if ((pBytes[i] == header[0]) && (pBytes[i + 1] == header[1]) && (pBytes[i + 2] == header[2]) && (pBytes[i + 3] == header[3])) { - - //System.err.println("FOUND END OF HEADER!"); - return i + 4; - } - } - - // Check last 3 bytes, to check if we have a partial match - if ((pEnd - 1 >= 0) && (pBytes[pEnd - 1] == header[0])) { - - //System.err.println("FOUND LAST BYTE"); - return -2; // LAST BYTE - } - else if ((pEnd - 2 >= 0) && (pBytes[pEnd - 2] == header[0]) && (pBytes[pEnd - 1] == header[1])) { - - //System.err.println("FOUND LAST TWO BYTES"); - return -3; // LAST TWO BYTES - } - else if ((pEnd - 3 >= 0) && (pBytes[pEnd - 3] == header[0]) && (pBytes[pEnd - 2] == header[1]) && (pBytes[pEnd - 1] == header[2])) { - - //System.err.println("FOUND LAST THREE BYTES"); - return -4; // LAST THREE BYTES - } - return -1; // NO BYTES MATCH - } - - /** - * Reads the header part of the response, and copies it to a different - * InputStream. - */ - private static InputStream detatchResponseHeader(BufferedInputStream pIS) throws IOException { - // Store header in byte array - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - - pIS.mark(BUF_SIZE); - byte[] buffer = new byte[BUF_SIZE]; - int length; - int headerEnd; - - // Read from iput, store in bytes - while ((length = pIS.read(buffer)) != -1) { - - // End of header? - headerEnd = findEndOfHeader(buffer, length); - if (headerEnd >= 0) { - - // Write rest - bytes.write(buffer, 0, headerEnd); - - // Go back to last mark - pIS.reset(); - - // Position stream to right after header, and exit loop - pIS.skip(headerEnd); - break; - } - else if (headerEnd < -1) { - - // Write partial (except matching header bytes) - bytes.write(buffer, 0, length - 4); - - // Go back to last mark - pIS.reset(); - - // Position stream to right before potential header end - pIS.skip(length - 4); - } - else { - - // Write all - bytes.write(buffer, 0, length); - } - - // Can't read more than BUF_SIZE ahead anyway - pIS.mark(BUF_SIZE); - } - return new ByteArrayInputStream(bytes.toByteArray()); - } - - /** - * Pareses the response header fields. - */ - private static Properties parseHeaderFields(String[] pHeaders) { - Properties headers = new Properties(); - - // Get header information - int split; - String field; - String value; - - for (String header : pHeaders) { - //System.err.println(pHeaders[i]); - if ((split = header.indexOf(":")) > 0) { - - // Read & parse..? - field = header.substring(0, split); - value = header.substring(split + 1); - - //System.err.println(field + ": " + value.trim()); - headers.setProperty(StringUtil.toLowerCase(field), value.trim()); - } - } - return headers; - } - - /** - * Parses the response headers. - */ - private static String[] parseResponseHeader(InputStream pIS) throws IOException { - List headers = new ArrayList(); - - // Wrap Stream in Reader - BufferedReader in = new BufferedReader(new InputStreamReader(pIS)); - - // Get response status - String header; - - while ((header = in.readLine()) != null) { - //System.err.println(header); - headers.add(header); - } - return headers.toArray(new String[headers.size()]); - } - - /** - * A FilterInputStream that wraps HTTP streams, with given content-length. - */ - protected static class FixedLengthInputStream extends FilterInputStream { - - private int mBytesLeft = 0; - - protected FixedLengthInputStream(InputStream pIS, int pLength) { - super(pIS); - mBytesLeft = pLength; - } - - public int available() throws IOException { - int available = in.available(); - - return ((available < mBytesLeft) - ? available - : mBytesLeft); - } - - public int read() throws IOException { - if (mBytesLeft-- > 0) { - return in.read(); - } - return -1; - } - - public int read(byte[] pBytes, int pOffset, int pLength) throws IOException { - int read; - - if (mBytesLeft <= 0) { - return -1; // EOF - } - else if (mBytesLeft < pLength) { - - // Read all available - read = in.read(pBytes, pOffset, mBytesLeft); - - //System.err.println("Reading partial: " + read); - mBytesLeft -= read; - return read; - } - - // Just read - read = in.read(pBytes, pOffset, pLength); - - //System.err.println("Reading all avail: " + read); - mBytesLeft -= read; - return read; - } - } - - /** - * A FilterInputStream that wraps HTTP 1.1 "chunked" transfer mode. - */ - protected static class ChunkedInputStream extends FilterInputStream { - - private int mAvailableInCurrentChunk = 0; - - /** - * Creates an input streams that removes the "chunk-headers" and - * makes it look like any other input stream. - */ - protected ChunkedInputStream(InputStream pIS) { - - super(pIS); - if (pIS == null) { - throw new IllegalArgumentException("InputStream may not be null!"); - } - } - - /** - * Returns the number of bytes that can be read from this input stream - * without blocking. - *

- * This version returns whatever is less of in.available() and the - * length of the current chunk. - * - * @return the number of bytes that can be read from the input stream - * without blocking. - * @throws IOException if an I/O error occurs. - * @see #in - */ - public int available() throws IOException { - - if (mAvailableInCurrentChunk == 0) { - mAvailableInCurrentChunk = parseChunkSize(); - } - int realAvail = in.available(); - - return (mAvailableInCurrentChunk < realAvail) - ? mAvailableInCurrentChunk - : realAvail; - } - - /** - * Reads up to len bytes of data from this input stream into an array - * of bytes. This method blocks until some input is available. - *

- * This version will read up to len bytes of data, or as much as is - * available in the current chunk. If there is no more data in the - * curernt chunk, the method will read the size of the next chunk, and - * read from that, until the last chunk is read (a chunk with a size of - * 0). - * - * @param pBytes the buffer into which the data is read. - * @param pOffset the start offset of the data. - * @param pLength the maximum number of bytes read. - * @return the total number of bytes read into the buffer, or -1 if - * there is no more data because the end of the stream has been - * reached. - * @throws IOException if an I/O error occurs. - * @see #in - */ - public int read(byte[] pBytes, int pOffset, int pLength) throws IOException { - - //System.err.println("Avail: " + mAvailableInCurrentChunk - // + " length: " + pLength); - int read; - - if (mAvailableInCurrentChunk == -1) { - return -1; // EOF - } - if (mAvailableInCurrentChunk == 0) { - - //System.err.println("Nothing to read, parsing size!"); - // If nothing is read so far, read chunk header - mAvailableInCurrentChunk = parseChunkSize(); - return read(pBytes, pOffset, pLength); - } - else if (mAvailableInCurrentChunk < pLength) { - - // Read all available - read = in.read(pBytes, pOffset, mAvailableInCurrentChunk); - - //System.err.println("Reading partial: " + read); - mAvailableInCurrentChunk -= read; - return read; - } - - // Just read - read = in.read(pBytes, pOffset, pLength); - - //System.err.println("Reading all avail: " + read); - mAvailableInCurrentChunk -= read; - return read; - } - - /** - * Reads the next byte of data from this input stream. The value byte - * is returned as an int in the range 0 to 255. If no byte is available - * because the end of the stream has been reached, the value -1 is - * returned. This method blocks until input data is available, the end - * of the stream is detected, or an exception is thrown. - *

- * This version reads one byte of data from the current chunk as long - * as there is more data in the chunk. If there is no more data in the - * curernt chunk, the method will read the size of the next chunk, and - * read from that, until the last chunk is read (a chunk with a size of - * 0). - * - * @return the next byte of data, or -1 if the end of the stream is - * reached. - * @see #in - */ - public int read() throws IOException { - - // We have no data, parse chunk header - if (mAvailableInCurrentChunk == -1) { - return -1; - } - else if (mAvailableInCurrentChunk == 0) { - - // Next chunk! - mAvailableInCurrentChunk = parseChunkSize(); - return read(); - } - mAvailableInCurrentChunk--; - return in.read(); - } - - /** - * Reads the chunk size from the chunk header - * {@code chunk-size [SP chunk-extension] CRLF}. - * The chunk-extension is simply discarded. - * - * @return the length of the current chunk, or -1 if the current chunk - * is the last-chunk (a chunk with the size of 0). - */ - protected int parseChunkSize() throws IOException { - - StringBuilder buf = new StringBuilder(); - int b; - - // read chunk-size, chunk-extension (if any) and CRLF - while ((b = in.read()) > 0) { - if ((b == '\r') && (in.read() == '\n')) { // Should be no CR or LF - break; // except for this one... - } - buf.append((char) b); - } - String line = buf.toString(); - - // Happens, as we don't read CRLF off the end of the chunk data... - if (line.length() == 0) { - return 0; - } - - // Discard any chunk-extensions, and read size (HEX). - int spIdx = line.indexOf(' '); - int size = Integer.parseInt(((spIdx >= 0) - ? line.substring(0, spIdx) - : line), 16); - - // This is the last chunk (=EOF) - if (size == 0) { - return -1; - } - return size; - } - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/net/NetUtil.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/net/NetUtil.java deleted file mode 100755 index 09d94938..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/net/NetUtil.java +++ /dev/null @@ -1,1258 +0,0 @@ -package com.twelvemonkeys.net; - -import com.twelvemonkeys.io.FileUtil; -import com.twelvemonkeys.lang.StringUtil; -import com.twelvemonkeys.util.CollectionUtil; - -import java.io.*; -import java.net.*; -import java.net.HttpURLConnection; -import java.util.Iterator; -import java.util.Map; -import java.util.Properties; - -/** - * Utility class with network related methods. - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/net/NetUtil.java#2 $ - */ -public final class NetUtil { - - private final static String VERSION_ID = "NetUtil/2.1"; - - private static Authenticator sAuthenticator = null; - - private final static int BUF_SIZE = 8192; - private final static String HTTP = "http://"; - private final static String HTTPS = "https://"; - - /** - * Field HTTP_PROTOCOL - */ - public final static String HTTP_PROTOCOL = "http"; - - /** - * Field HTTPS_PROTOCOL - */ - public final static String HTTPS_PROTOCOL = "https"; - - /** - * Field HTTP_GET - */ - public final static String HTTP_GET = "GET"; - - /** - * Field HTTP_POST - */ - public final static String HTTP_POST = "POST"; - - /** - * Field HTTP_HEAD - */ - public final static String HTTP_HEAD = "HEAD"; - - /** - * Field HTTP_OPTIONS - */ - public final static String HTTP_OPTIONS = "OPTIONS"; - - /** - * Field HTTP_PUT - */ - public final static String HTTP_PUT = "PUT"; - - /** - * Field HTTP_DELETE - */ - public final static String HTTP_DELETE = "DELETE"; - - /** - * Field HTTP_TRACE - */ - public final static String HTTP_TRACE = "TRACE"; - - /** - * Creates a NetUtil. - * This class has only static methods and members, and should not be - * instantiated. - */ - private NetUtil() { - } - - /** - * Main method, reads data from a URL and, optionally, writes it to stdout or a file. - * @param pArgs command line arguemnts - * @throws java.io.IOException if an I/O exception occurs - */ - public static void main(String[] pArgs) throws IOException { - // params: - int timeout = 0; - boolean followRedirects = true; - boolean debugHeaders = false; - String requestPropertiesFile = null; - String requestHeaders = null; - String postData = null; - File putData = null; - int argIdx = 0; - boolean errArgs = false; - boolean writeToFile = false; - boolean writeToStdOut = false; - String outFileName = null; - - while ((argIdx < pArgs.length) && (pArgs[argIdx].charAt(0) == '-') && (pArgs[argIdx].length() >= 2)) { - if ((pArgs[argIdx].charAt(1) == 't') || pArgs[argIdx].equals("--timeout")) { - argIdx++; - try { - timeout = Integer.parseInt(pArgs[argIdx++]); - } - catch (NumberFormatException nfe) { - errArgs = true; - break; - } - } - else if ((pArgs[argIdx].charAt(1) == 'd') || pArgs[argIdx].equals("--debugheaders")) { - debugHeaders = true; - argIdx++; - } - else if ((pArgs[argIdx].charAt(1) == 'n') || pArgs[argIdx].equals("--nofollowredirects")) { - followRedirects = false; - argIdx++; - } - else if ((pArgs[argIdx].charAt(1) == 'r') || pArgs[argIdx].equals("--requestproperties")) { - argIdx++; - requestPropertiesFile = pArgs[argIdx++]; - } - else if ((pArgs[argIdx].charAt(1) == 'p') || pArgs[argIdx].equals("--postdata")) { - argIdx++; - postData = pArgs[argIdx++]; - } - else if ((pArgs[argIdx].charAt(1) == 'u') || pArgs[argIdx].equals("--putdata")) { - argIdx++; - putData = new File(pArgs[argIdx++]); - if (!putData.exists()) { - errArgs = true; - break; - } - } - else if ((pArgs[argIdx].charAt(1) == 'h') || pArgs[argIdx].equals("--header")) { - argIdx++; - requestHeaders = pArgs[argIdx++]; - } - else if ((pArgs[argIdx].charAt(1) == 'f') || pArgs[argIdx].equals("--file")) { - argIdx++; - writeToFile = true; - - // Get optional file name - if (!((argIdx >= (pArgs.length - 1)) || (pArgs[argIdx].charAt(0) == '-'))) { - outFileName = pArgs[argIdx++]; - } - } - else if ((pArgs[argIdx].charAt(1) == 'o') || pArgs[argIdx].equals("--output")) { - argIdx++; - writeToStdOut = true; - } - else { - System.err.println("Unknown option \"" + pArgs[argIdx++] + "\""); - } - } - if (errArgs || (pArgs.length < (argIdx + 1))) { - System.err.println("Usage: java NetUtil [-f|--file []] [-d|--debugheaders] [-h|--header

] [-p|--postdata ] [-u|--putdata ] [-r|--requestProperties ] [-t|--timeout ] [-n|--nofollowredirects] fromUrl"); - System.exit(5); - } - String url = pArgs[argIdx/*++*/]; - - // DONE ARGS - // Get request properties - Properties requestProperties = new Properties(); - - if (requestPropertiesFile != null) { - - // Just read, no exception handling... - requestProperties.load(new FileInputStream(new File(requestPropertiesFile))); - } - if (requestHeaders != null) { - - // Get request headers - String[] headerPairs = StringUtil.toStringArray(requestHeaders, ","); - - for (String headerPair : headerPairs) { - String[] pair = StringUtil.toStringArray(headerPair, ":"); - String key = (pair.length > 0) - ? pair[0].trim() - : null; - String value = (pair.length > 1) - ? pair[1].trim() - : ""; - - if (key != null) { - requestProperties.setProperty(key, value); - } - } - } - HttpURLConnection conn; - - // Create connection - URL reqURL = getURLAndSetAuthorization(url, requestProperties); - - conn = createHttpURLConnection(reqURL, requestProperties, followRedirects, timeout); - - // POST - if (postData != null) { - // HTTP POST method - conn.setRequestMethod(HTTP_POST); - - // Set entity headers - conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); - conn.setRequestProperty("Content-Length", String.valueOf(postData.length())); - conn.setRequestProperty("Content-Encoding", "ISO-8859-1"); - - // Get outputstream (this is where the connect actually happens) - OutputStream os = conn.getOutputStream(); - - System.err.println("OutputStream: " + os.getClass().getName() + "@" + System.identityHashCode(os)); - OutputStreamWriter writer = new OutputStreamWriter(os, "ISO-8859-1"); - - // Write post data to the stream - writer.write(postData); - writer.write("\r\n"); - - //writer.flush(); - writer.close(); // Does this close the underlying stream? - } - // PUT - else if (putData != null) { - // HTTP PUT method - conn.setRequestMethod(HTTP_PUT); - - // Set entity headers - //conn.setRequestProperty("Content-Type", "???"); - // TODO: Set Content-Type to correct type? - // TODO: Set content-encoding? Or can binary data be sent directly? - conn.setRequestProperty("Content-Length", String.valueOf(putData.length())); - - // Get outputstream (this is where the connect actually happens) - OutputStream os = conn.getOutputStream(); - - System.err.println("OutputStream: " + os.getClass().getName() + "@" + System.identityHashCode(os)); - - // Write put data to the stream - FileUtil.copy(new FileInputStream(putData), os); - - os.close(); - } - - // - InputStream is; - - if (conn.getResponseCode() == 200) { - - // Connect and get stream - is = conn.getInputStream(); - } - else { - is = conn.getErrorStream(); - } - - // - if (debugHeaders) { - System.err.println("Request (debug):"); - System.err.println(conn.getClass()); - System.err.println("Response (debug):"); - - // Headerfield 0 is response code - System.err.println(conn.getHeaderField(0)); - - // Loop from 1, as headerFieldKey(0) == null... - for (int i = 1; ; i++) { - String key = conn.getHeaderFieldKey(i); - - // Seems to be the way to loop through them all... - if (key == null) { - break; - } - System.err.println(key + ": " + conn.getHeaderField(key)); - } - } - - // Create output file if specified - OutputStream os; - - if (writeToFile) { - if (outFileName == null) { - outFileName = reqURL.getFile(); - if (StringUtil.isEmpty(outFileName)) { - outFileName = conn.getHeaderField("Location"); - if (StringUtil.isEmpty(outFileName)) { - outFileName = "index"; - - // Find a suitable extension - // TODO: Replace with MIME-type util with MIME/file ext mapping - String ext = conn.getContentType(); - - if (!StringUtil.isEmpty(ext)) { - int idx = ext.lastIndexOf('/'); - - if (idx >= 0) { - ext = ext.substring(idx + 1); - } - idx = ext.indexOf(';'); - if (idx >= 0) { - ext = ext.substring(0, idx); - } - outFileName += "." + ext; - } - } - } - int idx = outFileName.lastIndexOf('/'); - - if (idx >= 0) { - outFileName = outFileName.substring(idx + 1); - } - idx = outFileName.indexOf('?'); - if (idx >= 0) { - outFileName = outFileName.substring(0, idx); - } - } - File outFile = new File(outFileName); - - if (!outFile.createNewFile()) { - if (outFile.exists()) { - System.err.println("Cannot write to file " + outFile.getAbsolutePath() + ", file allready exists."); - } - else { - System.err.println("Cannot write to file " + outFile.getAbsolutePath() + ", check write permissions."); - } - System.exit(5); - } - os = new FileOutputStream(outFile); - } - else if (writeToStdOut) { - os = System.out; - } - else { - os = null; - } - - // Get data. - if ((writeToFile || writeToStdOut) && is != null) { - FileUtil.copy(is, os); - } - - /* - Hashtable postData = new Hashtable(); - postData.put("SearchText", "condition"); - - try { - InputStream in = getInputStreamHttpPost(pArgs[argIdx], postData, - props, true, 0); - out = new FileOutputStream(file); - FileUtil.copy(in, out); - } - catch (Exception e) { - System.err.println("Error: " + e); - e.printStackTrace(System.err); - continue; - } - */ - } - - /* - public static class Cookie { - String mName = null; - String mValue = null; - - public Cookie(String pName, String pValue) { - mName = pName; - mValue = pValue; - } - - public String toString() { - return mName + "=" + mValue; - } - */ - - /* - // Just a way to set cookies.. - if (pCookies != null) { - String cookieStr = ""; - for (int i = 0; i < pCookies.length; i++) - cookieStr += ((i == pCookies.length) ? pCookies[i].toString() - : pCookies[i].toString() + ";"); - - // System.out.println("Cookie: " + cookieStr); - - conn.setRequestProperty("Cookie", cookieStr); - } - */ - - /* - } - */ - - /** - * Test if the given URL is using HTTP protocol. - * - * @param pURL the url to condition - * @return true if the protocol is HTTP. - */ - public static boolean isHttpURL(String pURL) { - return ((pURL != null) && pURL.startsWith(HTTP)); - } - - /** - * Test if the given URL is using HTTP protocol. - * - * @param pURL the url to condition - * @return true if the protocol is HTTP. - */ - public static boolean isHttpURL(URL pURL) { - return ((pURL != null) && pURL.getProtocol().equals("http")); - } - - /** - * Gets the content from a given URL, and returns it as a byte array. - * Supports basic HTTP - * authentication, using a URL string similar to most browsers. - *

- * NOTE: If you supply a username and password for HTTP - * authentication, this method uses the java.net.Authenticator's static - * {@code setDefault()} method, that can only be set ONCE. This - * means that if the default Authenticator is allready set, this method - * will fail. - * It also means if any other piece of code tries to register a new default - * Authenticator within the current VM, it will fail. - * - * @param pURL A String containing the URL, on the form - * [http://][:@]servername[/file.ext] - * where everything in brackets are optional. - * @return a byte array with the URL contents. If an error occurs, the - * returned array may be zero-length, but not null. - * @throws MalformedURLException if the urlName parameter is not a valid - * URL. Note that the protocol cannot be anything but HTTP. - * @throws FileNotFoundException if there is no file at the given URL. - * @throws IOException if an error occurs during transfer. - * @see java.net.Authenticator - * @see SimpleAuthenticator - */ - public static byte[] getBytesHttp(String pURL) throws IOException { - return getBytesHttp(pURL, 0); - } - - /** - * Gets the content from a given URL, and returns it as a byte array. - * - * @param pURL the URL to get. - * @return a byte array with the URL contents. If an error occurs, the - * returned array may be zero-length, but not null. - * @throws FileNotFoundException if there is no file at the given URL. - * @throws IOException if an error occurs during transfer. - * @see #getBytesHttp(String) - */ - public static byte[] getBytesHttp(URL pURL) throws IOException { - return getBytesHttp(pURL, 0); - } - - /** - * Gets the InputStream from a given URL. Supports basic HTTP - * authentication, using a URL string similar to most browsers. - *

- * NOTE: If you supply a username and password for HTTP - * authentication, this method uses the java.net.Authenticator's static - * {@code setDefault()} method, that can only be set ONCE. This - * means that if the default Authenticator is allready set, this method - * will fail. - * It also means if any other piece of code tries to register a new default - * Authenticator within the current VM, it will fail. - * - * @param pURL A String containing the URL, on the form - * [http://][:@]servername[/file.ext] - * where everything in brackets are optional. - * @return an input stream that reads from the connection created by the - * given URL. - * @throws MalformedURLException if the urlName parameter specifies an - * unknown protocol, or does not form a valid URL. - * Note that the protocol cannot be anything but HTTP. - * @throws FileNotFoundException if there is no file at the given URL. - * @throws IOException if an error occurs during transfer. - * @see java.net.Authenticator - * @see SimpleAuthenticator - */ - public static InputStream getInputStreamHttp(String pURL) throws IOException { - return getInputStreamHttp(pURL, 0); - } - - /** - * Gets the InputStream from a given URL. - * - * @param pURL the URL to get. - * @return an input stream that reads from the connection created by the - * given URL. - * @throws FileNotFoundException if there is no file at the given URL. - * @throws IOException if an error occurs during transfer. - * @see #getInputStreamHttp(String) - */ - public static InputStream getInputStreamHttp(URL pURL) throws IOException { - return getInputStreamHttp(pURL, 0); - } - - /** - * Gets the InputStream from a given URL, with the given timeout. - * The timeout must be > 0. A timeout of zero is interpreted as an - * infinite timeout. Supports basic HTTP - * authentication, using a URL string similar to most browsers. - *

- * Implementation note: If the timeout parameter is greater than 0, - * this method uses my own implementation of - * java.net.HttpURLConnection, that uses plain sockets, to create an - * HTTP connection to the given URL. The {@code read} methods called - * on the returned InputStream, will block only for the specified timeout. - * If the timeout expires, a java.io.InterruptedIOException is raised. This - * might happen BEFORE OR AFTER this method returns, as the HTTP headers - * will be read and parsed from the InputStream before this method returns, - * while further read operations on the returned InputStream might be - * performed at a later stage. - *
- *
- * - * @param pURL the URL to get. - * @param pTimeout the specified timeout, in milliseconds. - * @return an input stream that reads from the socket connection, created - * from the given URL. - * @throws MalformedURLException if the url parameter specifies an - * unknown protocol, or does not form a valid URL. - * @throws UnknownHostException if the IP address for the given URL cannot - * be resolved. - * @throws FileNotFoundException if there is no file at the given URL. - * @throws IOException if an error occurs during transfer. - * @see #getInputStreamHttp(URL,int) - * @see java.net.Socket - * @see java.net.Socket#setSoTimeout(int) setSoTimeout - * @see java.io.InterruptedIOException - * @see RFC 2616 - */ - public static InputStream getInputStreamHttp(String pURL, int pTimeout) throws IOException { - return getInputStreamHttp(pURL, null, true, pTimeout); - } - - /** - * Gets the InputStream from a given URL, with the given timeout. - * The timeout must be > 0. A timeout of zero is interpreted as an - * infinite timeout. Supports basic HTTP - * authentication, using a URL string similar to most browsers. - *

- * Implementation note: If the timeout parameter is greater than 0, - * this method uses my own implementation of - * java.net.HttpURLConnection, that uses plain sockets, to create an - * HTTP connection to the given URL. The {@code read} methods called - * on the returned InputStream, will block only for the specified timeout. - * If the timeout expires, a java.io.InterruptedIOException is raised. This - * might happen BEFORE OR AFTER this method returns, as the HTTP headers - * will be read and parsed from the InputStream before this method returns, - * while further read operations on the returned InputStream might be - * performed at a later stage. - *
- *
- * - * @param pURL the URL to get. - * @param pProperties the request header properties. - * @param pFollowRedirects specifying wether redirects should be followed. - * @param pTimeout the specified timeout, in milliseconds. - * @return an input stream that reads from the socket connection, created - * from the given URL. - * @throws MalformedURLException if the url parameter specifies an - * unknown protocol, or does not form a valid URL. - * @throws UnknownHostException if the IP address for the given URL cannot - * be resolved. - * @throws FileNotFoundException if there is no file at the given URL. - * @throws IOException if an error occurs during transfer. - * @see #getInputStreamHttp(URL,int) - * @see java.net.Socket - * @see java.net.Socket#setSoTimeout(int) setSoTimeout - * @see java.io.InterruptedIOException - * @see RFC 2616 - */ - public static InputStream getInputStreamHttp(final String pURL, final Properties pProperties, final boolean pFollowRedirects, final int pTimeout) - throws IOException { - - // Make sure we have properties - Properties properties = pProperties != null ? pProperties : new Properties(); - - //URL url = getURLAndRegisterPassword(pURL); - URL url = getURLAndSetAuthorization(pURL, properties); - - //unregisterPassword(url); - return getInputStreamHttp(url, properties, pFollowRedirects, pTimeout); - } - - /** - * Registers the password from the URL string, and returns the URL object. - * - * @param pURL the string representation of the URL, possibly including authorization part - * @param pProperties the - * @return the URL created from {@code pURL}. - * @throws java.net.MalformedURLException if there's a syntax error in {@code pURL} - */ - private static URL getURLAndSetAuthorization(final String pURL, final Properties pProperties) throws MalformedURLException { - String url = pURL; - // Split user/password away from url - String userPass = null; - String protocolPrefix = HTTP; - int httpIdx = url.indexOf(HTTPS); - - if (httpIdx >= 0) { - protocolPrefix = HTTPS; - url = url.substring(httpIdx + HTTPS.length()); - } - else { - httpIdx = url.indexOf(HTTP); - if (httpIdx >= 0) { - url = url.substring(httpIdx + HTTP.length()); - } - } - - // Get authorization part - int atIdx = url.indexOf("@"); - - if (atIdx >= 0) { - userPass = url.substring(0, atIdx); - url = url.substring(atIdx + 1); - } - - // Set authorization if user/password is present - if (userPass != null) { - // System.out.println("Setting password ("+ userPass + ")!"); - pProperties.setProperty("Authorization", "Basic " + BASE64.encode(userPass.getBytes())); - } - - // Return URL - return new URL(protocolPrefix + url); - } - - /** - * Gets the InputStream from a given URL, with the given timeout. - * The timeout must be > 0. A timeout of zero is interpreted as an - * infinite timeout. - *

- * Implementation note: If the timeout parameter is greater than 0, - * this method uses my own implementation of - * java.net.HttpURLConnection, that uses plain sockets, to create an - * HTTP connection to the given URL. The {@code read} methods called - * on the returned InputStream, will block only for the specified timeout. - * If the timeout expires, a java.io.InterruptedIOException is raised. This - * might happen BEFORE OR AFTER this method returns, as the HTTP headers - * will be read and parsed from the InputStream before this method returns, - * while further read operations on the returned InputStream might be - * performed at a later stage. - *
- *
- * - * @param pURL the URL to get. - * @param pTimeout the specified timeout, in milliseconds. - * @return an input stream that reads from the socket connection, created - * from the given URL. - * @throws UnknownHostException if the IP address for the given URL cannot - * be resolved. - * @throws FileNotFoundException if there is no file at the given URL. - * @throws IOException if an error occurs during transfer. - * @see com.twelvemonkeys.net.HttpURLConnection - * @see java.net.Socket - * @see java.net.Socket#setSoTimeout(int) setSoTimeout - * @see HttpURLConnection - * @see java.io.InterruptedIOException - * @see RFC 2616 - */ - public static InputStream getInputStreamHttp(URL pURL, int pTimeout) throws IOException { - return getInputStreamHttp(pURL, null, true, pTimeout); - } - - /** - * Gets the InputStream from a given URL, with the given timeout. - * The timeout must be > 0. A timeout of zero is interpreted as an - * infinite timeout. Supports basic HTTP - * authentication, using a URL string similar to most browsers. - *

- * Implementation note: If the timeout parameter is greater than 0, - * this method uses my own implementation of - * java.net.HttpURLConnection, that uses plain sockets, to create an - * HTTP connection to the given URL. The {@code read} methods called - * on the returned InputStream, will block only for the specified timeout. - * If the timeout expires, a java.io.InterruptedIOException is raised. This - * might happen BEFORE OR AFTER this method returns, as the HTTP headers - * will be read and parsed from the InputStream before this method returns, - * while further read operations on the returned InputStream might be - * performed at a later stage. - *
- *
- * - * @param pURL the URL to get. - * @param pProperties the request header properties. - * @param pFollowRedirects specifying wether redirects should be followed. - * @param pTimeout the specified timeout, in milliseconds. - * @return an input stream that reads from the socket connection, created - * from the given URL. - * @throws UnknownHostException if the IP address for the given URL cannot - * be resolved. - * @throws FileNotFoundException if there is no file at the given URL. - * @throws IOException if an error occurs during transfer. - * @see #getInputStreamHttp(URL,int) - * @see java.net.Socket - * @see java.net.Socket#setSoTimeout(int) setSoTimeout - * @see java.io.InterruptedIOException - * @see RFC 2616 - */ - public static InputStream getInputStreamHttp(URL pURL, Properties pProperties, boolean pFollowRedirects, int pTimeout) - throws IOException { - - // Open the connection, and get the stream - HttpURLConnection conn = createHttpURLConnection(pURL, pProperties, pFollowRedirects, pTimeout); - - // HTTP GET method - conn.setRequestMethod(HTTP_GET); - - // This is where the connect happens - InputStream is = conn.getInputStream(); - - // We only accept the 200 OK message - if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) { - throw new IOException("The request gave the response: " + conn.getResponseCode() + ": " + conn.getResponseMessage()); - } - return is; - } - - /** - * Gets the InputStream from a given URL, with the given timeout. - * The timeout must be > 0. A timeout of zero is interpreted as an - * infinite timeout. Supports basic HTTP - * authentication, using a URL string similar to most browsers. - *

- * Implementation note: If the timeout parameter is greater than 0, - * this method uses my own implementation of - * java.net.HttpURLConnection, that uses plain sockets, to create an - * HTTP connection to the given URL. The {@code read} methods called - * on the returned InputStream, will block only for the specified timeout. - * If the timeout expires, a java.io.InterruptedIOException is raised. This - * might happen BEFORE OR AFTER this method returns, as the HTTP headers - * will be read and parsed from the InputStream before this method returns, - * while further read operations on the returned InputStream might be - * performed at a later stage. - *
- *
- * - * @param pURL the URL to get. - * @param pPostData the post data. - * @param pProperties the request header properties. - * @param pFollowRedirects specifying wether redirects should be followed. - * @param pTimeout the specified timeout, in milliseconds. - * @return an input stream that reads from the socket connection, created - * from the given URL. - * @throws MalformedURLException if the url parameter specifies an - * unknown protocol, or does not form a valid URL. - * @throws UnknownHostException if the IP address for the given URL cannot - * be resolved. - * @throws FileNotFoundException if there is no file at the given URL. - * @throws IOException if an error occurs during transfer. - */ - public static InputStream getInputStreamHttpPost(String pURL, Map pPostData, Properties pProperties, boolean pFollowRedirects, int pTimeout) - throws IOException { - - pProperties = pProperties != null ? pProperties : new Properties(); - - //URL url = getURLAndRegisterPassword(pURL); - URL url = getURLAndSetAuthorization(pURL, pProperties); - - //unregisterPassword(url); - return getInputStreamHttpPost(url, pPostData, pProperties, pFollowRedirects, pTimeout); - } - - /** - * Gets the InputStream from a given URL, with the given timeout. - * The timeout must be > 0. A timeout of zero is interpreted as an - * infinite timeout. Supports basic HTTP - * authentication, using a URL string similar to most browsers. - *

- * Implementation note: If the timeout parameter is greater than 0, - * this method uses my own implementation of - * java.net.HttpURLConnection, that uses plain sockets, to create an - * HTTP connection to the given URL. The {@code read} methods called - * on the returned InputStream, will block only for the specified timeout. - * If the timeout expires, a java.io.InterruptedIOException is raised. This - * might happen BEFORE OR AFTER this method returns, as the HTTP headers - * will be read and parsed from the InputStream before this method returns, - * while further read operations on the returned InputStream might be - * performed at a later stage. - *
- *
- * - * @param pURL the URL to get. - * @param pPostData the post data. - * @param pProperties the request header properties. - * @param pFollowRedirects specifying wether redirects should be followed. - * @param pTimeout the specified timeout, in milliseconds. - * @return an input stream that reads from the socket connection, created - * from the given URL. - * @throws UnknownHostException if the IP address for the given URL cannot - * be resolved. - * @throws FileNotFoundException if there is no file at the given URL. - * @throws IOException if an error occurs during transfer. - */ - public static InputStream getInputStreamHttpPost(URL pURL, Map pPostData, Properties pProperties, boolean pFollowRedirects, int pTimeout) - throws IOException { - // Open the connection, and get the stream - HttpURLConnection conn = createHttpURLConnection(pURL, pProperties, pFollowRedirects, pTimeout); - - // HTTP POST method - conn.setRequestMethod(HTTP_POST); - - // Iterate over and create post data string - StringBuilder postStr = new StringBuilder(); - - if (pPostData != null) { - Iterator data = pPostData.entrySet().iterator(); - - while (data.hasNext()) { - Map.Entry entry = (Map.Entry) data.next(); - - // Properties key/values can be safely cast to strings - // Encode the string - postStr.append(URLEncoder.encode((String) entry.getKey(), "UTF-8")); - postStr.append('='); - postStr.append(URLEncoder.encode(entry.getValue().toString(), "UTF-8")); - - if (data.hasNext()) { - postStr.append('&'); - } - } - } - - // Set entity headers - String encoding = conn.getRequestProperty("Content-Encoding"); - if (StringUtil.isEmpty(encoding)) { - encoding = "UTF-8"; - } - conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); - conn.setRequestProperty("Content-Length", String.valueOf(postStr.length())); - conn.setRequestProperty("Content-Encoding", encoding); - - // Get outputstream (this is where the connect actually happens) - OutputStream os = conn.getOutputStream(); - OutputStreamWriter writer = new OutputStreamWriter(os, encoding); - - // Write post data to the stream - writer.write(postStr.toString()); - writer.write("\r\n"); - writer.close(); // Does this close the underlying stream? - - // Get the inputstream - InputStream is = conn.getInputStream(); - - // We only accept the 200 OK message - // TODO: Accept all 200 messages, like ACCEPTED, CREATED or NO_CONTENT? - if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) { - throw new IOException("The request gave the response: " + conn.getResponseCode() + ": " + conn.getResponseMessage()); - } - return is; - } - - /** - * Creates a HTTP connection to the given URL. - * - * @param pURL the URL to get. - * @param pProperties connection properties. - * @param pFollowRedirects specifies whether we should follow redirects. - * @param pTimeout the specified timeout, in milliseconds. - * @return a HttpURLConnection - * @throws UnknownHostException if the hostname in the URL cannot be found. - * @throws IOException if an I/O exception occurs. - */ - public static HttpURLConnection createHttpURLConnection(URL pURL, Properties pProperties, boolean pFollowRedirects, int pTimeout) - throws IOException { - - // Open the connection, and get the stream - HttpURLConnection conn; - - if (pTimeout > 0) { - // Supports timeout - conn = new com.twelvemonkeys.net.HttpURLConnection(pURL, pTimeout); - } - else { - // Faster, more compatible - conn = (HttpURLConnection) pURL.openConnection(); - } - - // Set user agent - if ((pProperties == null) || !pProperties.containsKey("User-Agent")) { - conn.setRequestProperty("User-Agent", - VERSION_ID - + " (" + System.getProperty("os.name") + "/" + System.getProperty("os.version") + "; " - + System.getProperty("os.arch") + "; " - + System.getProperty("java.vm.name") + "/" + System.getProperty("java.vm.version") + ")"); - } - - // Set request properties - if (pProperties != null) { - for (Map.Entry entry : pProperties.entrySet()) { - // Properties key/values can be safely cast to strings - conn.setRequestProperty((String) entry.getKey(), entry.getValue().toString()); - } - } - - try { - // Breaks with JRE1.2? - conn.setInstanceFollowRedirects(pFollowRedirects); - } - catch (LinkageError le) { - // This is the best we can do... - HttpURLConnection.setFollowRedirects(pFollowRedirects); - System.err.println("You are using an old Java Spec, consider upgrading."); - System.err.println("java.net.HttpURLConnection.setInstanceFollowRedirects(" + pFollowRedirects + ") failed."); - - //le.printStackTrace(System.err); - } - - conn.setDoInput(true); - conn.setDoOutput(true); - - //conn.setUseCaches(true); - return conn; - } - - /** - * This is a hack to get around the protected constructors in - * HttpURLConnection, should maybe consider registering and do things - * properly... - */ - - /* - private static class TimedHttpURLConnection - extends com.twelvemonkeys.net.HttpURLConnection { - TimedHttpURLConnection(URL pURL, int pTimeout) { - super(pURL, pTimeout); - } - } - */ - - /** - * Gets the content from a given URL, with the given timeout. - * The timeout must be > 0. A timeout of zero is interpreted as an - * infinite timeout. Supports basic HTTP - * authentication, using a URL string similar to most browsers. - *

- * Implementation note: If the timeout parameter is greater than 0, - * this method uses my own implementation of - * java.net.HttpURLConnection, that uses plain sockets, to create an - * HTTP connection to the given URL. The {@code read} methods called - * on the returned InputStream, will block only for the specified timeout. - * If the timeout expires, a java.io.InterruptedIOException is raised. - *
- *
- * - * @param pURL the URL to get. - * @param pTimeout the specified timeout, in milliseconds. - * @return a byte array that is read from the socket connection, created - * from the given URL. - * @throws MalformedURLException if the url parameter specifies an - * unknown protocol, or does not form a valid URL. - * @throws UnknownHostException if the IP address for the given URL cannot - * be resolved. - * @throws FileNotFoundException if there is no file at the given URL. - * @throws IOException if an error occurs during transfer. - * @see #getBytesHttp(URL,int) - * @see java.net.Socket - * @see java.net.Socket#setSoTimeout(int) setSoTimeout - * @see java.io.InterruptedIOException - * @see RFC 2616 - */ - public static byte[] getBytesHttp(String pURL, int pTimeout) throws IOException { - // Get the input stream from the url - InputStream in = new BufferedInputStream(getInputStreamHttp(pURL, pTimeout), BUF_SIZE * 2); - - // Get all the bytes in loop - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - int count; - byte[] buffer = new byte[BUF_SIZE]; - - try { - while ((count = in.read(buffer)) != -1) { - // NOTE: According to the J2SE API doc, read(byte[]) will read - // at least 1 byte, or return -1, if end-of-file is reached. - bytes.write(buffer, 0, count); - } - } - finally { - - // Close the buffer - in.close(); - } - return bytes.toByteArray(); - } - - /** - * Gets the content from a given URL, with the given timeout. - * The timeout must be > 0. A timeout of zero is interpreted as an - * infinite timeout. - *

- * Implementation note: If the timeout parameter is greater than 0, - * this method uses my own implementation of - * java.net.HttpURLConnection, that uses plain sockets, to create an - * HTTP connection to the given URL. The {@code read} methods called - * on the returned InputStream, will block only for the specified timeout. - * If the timeout expires, a java.io.InterruptedIOException is raised. - *
- *
- * - * @param pURL the URL to get. - * @param pTimeout the specified timeout, in milliseconds. - * @return an input stream that reads from the socket connection, created - * from the given URL. - * @throws UnknownHostException if the IP address for the given URL cannot - * be resolved. - * @throws FileNotFoundException if there is no file at the given URL. - * @throws IOException if an error occurs during transfer. - * @see #getInputStreamHttp(URL,int) - * @see com.twelvemonkeys.net.HttpURLConnection - * @see java.net.Socket - * @see java.net.Socket#setSoTimeout(int) setSoTimeout - * @see HttpURLConnection - * @see java.io.InterruptedIOException - * @see RFC 2616 - */ - public static byte[] getBytesHttp(URL pURL, int pTimeout) throws IOException { - // Get the input stream from the url - InputStream in = new BufferedInputStream(getInputStreamHttp(pURL, pTimeout), BUF_SIZE * 2); - - // Get all the bytes in loop - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - int count; - byte[] buffer = new byte[BUF_SIZE]; - - try { - while ((count = in.read(buffer)) != -1) { - // NOTE: According to the J2SE API doc, read(byte[]) will read - // at least 1 byte, or return -1, if end-of-file is reached. - bytes.write(buffer, 0, count); - } - } - finally { - - // Close the buffer - in.close(); - } - return bytes.toByteArray(); - } - - /** - * Unregisters the password asscociated with this URL - */ - - /* - private static void unregisterPassword(URL pURL) { - Authenticator auth = registerAuthenticator(); - if (auth != null && auth instanceof SimpleAuthenticator) - ((SimpleAuthenticator) auth) - .unregisterPasswordAuthentication(pURL); - } - */ - - /** - * Registers the password from the URL string, and returns the URL object. - */ - - /* - private static URL getURLAndRegisterPassword(String pURL) - throws MalformedURLException - { - // Split user/password away from url - String userPass = null; - String protocolPrefix = HTTP; - - int httpIdx = pURL.indexOf(HTTPS); - if (httpIdx >= 0) { - protocolPrefix = HTTPS; - pURL = pURL.substring(httpIdx + HTTPS.length()); - } - else { - httpIdx = pURL.indexOf(HTTP); - if (httpIdx >= 0) - pURL = pURL.substring(httpIdx + HTTP.length()); - } - - int atIdx = pURL.indexOf("@"); - if (atIdx >= 0) { - userPass = pURL.substring(0, atIdx); - pURL = pURL.substring(atIdx + 1); - } - - // Set URL - URL url = new URL(protocolPrefix + pURL); - - // Set Authenticator if user/password is present - if (userPass != null) { - // System.out.println("Setting password ("+ userPass + ")!"); - - int colIdx = userPass.indexOf(":"); - if (colIdx < 0) - throw new MalformedURLException("Error in username/password!"); - - String userName = userPass.substring(0, colIdx); - String passWord = userPass.substring(colIdx + 1); - - // Try to register the authenticator - // System.out.println("Trying to register authenticator!"); - Authenticator auth = registerAuthenticator(); - - // System.out.println("Got authenticator " + auth + "."); - - // Register our username/password with it - if (auth != null && auth instanceof SimpleAuthenticator) { - ((SimpleAuthenticator) auth) - .registerPasswordAuthentication(url, - new PasswordAuthentication(userName, - passWord.toCharArray())); - } - else { - // Not supported! - throw new RuntimeException("Could not register PasswordAuthentication"); - } - } - - return url; - } - */ - - /** - * Registers the Authenticator given in the system property - * {@code java.net.Authenticator}, or the default implementation - * ({@code com.twelvemonkeys.net.SimpleAuthenticator}). - *

- * BUG: What if authenticator has allready been set outside this class? - * - * @return The Authenticator created and set as default, or null, if it - * was not set as the default. However, there is no (clean) way to - * be sure the authenticator was set (the SimpleAuthenticator uses - * a hack to get around this), so it might be possible that the - * returned authenticator was not set as default... - * @see Authenticator#setDefault(Authenticator) - * @see SimpleAuthenticator - */ - public synchronized static Authenticator registerAuthenticator() { - if (sAuthenticator != null) { - return sAuthenticator; - } - - // Get the system property - String authenticatorName = System.getProperty("java.net.Authenticator"); - - // Try to get the Authenticator from the system property - if (authenticatorName != null) { - try { - Class authenticatorClass = Class.forName(authenticatorName); - - sAuthenticator = (Authenticator) authenticatorClass.newInstance(); - } - catch (ClassNotFoundException cnfe) { - // We should maybe rethrow this? - } - catch (InstantiationException ie) { - // Ignore - } - catch (IllegalAccessException iae) { - // Ignore - } - } - - // Get the default authenticator - if (sAuthenticator == null) { - sAuthenticator = SimpleAuthenticator.getInstance(); - } - - // Register authenticator as default - Authenticator.setDefault(sAuthenticator); - return sAuthenticator; - } - - /** - * Creates the InetAddress object from the given URL. - * Equivalent to calling {@code InetAddress.getByName(URL.getHost())} - * except that it returns null, instead of throwing UnknownHostException. - * - * @param pURL the URL to look up. - * @return the createad InetAddress, or null if the host was unknown. - * @see java.net.InetAddress - * @see java.net.URL - */ - public static InetAddress createInetAddressFromURL(URL pURL) { - try { - return InetAddress.getByName(pURL.getHost()); - } - catch (UnknownHostException e) { - return null; - } - } - - /** - * Creates an URL from the given InetAddress object, using the given - * protocol. - * Equivalent to calling - * {@code new URL(protocol, InetAddress.getHostName(), "")} - * except that it returns null, instead of throwing MalformedURLException. - * - * @param pIP the IP address to look up - * @param pProtocol the protocol to use in the new URL - * @return the created URL or null, if the URL could not be created. - * @see java.net.URL - * @see java.net.InetAddress - */ - public static URL createURLFromInetAddress(InetAddress pIP, String pProtocol) { - try { - return new URL(pProtocol, pIP.getHostName(), ""); - } - catch (MalformedURLException e) { - return null; - } - } - - /** - * Creates an URL from the given InetAddress object, using HTTP protocol. - * Equivalent to calling - * {@code new URL("http", InetAddress.getHostName(), "")} - * except that it returns null, instead of throwing MalformedURLException. - * - * @param pIP the IP address to look up - * @return the created URL or null, if the URL could not be created. - * @see java.net.URL - * @see java.net.InetAddress - */ - public static URL createURLFromInetAddress(InetAddress pIP) { - return createURLFromInetAddress(pIP, HTTP); - } - - /* - * TODO: Benchmark! - */ - static byte[] getBytesHttpOld(String pURL) throws IOException { - // Get the input stream from the url - InputStream in = new BufferedInputStream(getInputStreamHttp(pURL), BUF_SIZE * 2); - - // Get all the bytes in loop - byte[] bytes = new byte[0]; - int count; - byte[] buffer = new byte[BUF_SIZE]; - - try { - while ((count = in.read(buffer)) != -1) { - - // NOTE: According to the J2SE API doc, read(byte[]) will read - // at least 1 byte, or return -1, if end-of-file is reached. - bytes = (byte[]) CollectionUtil.mergeArrays(bytes, 0, bytes.length, buffer, 0, count); - } - } - finally { - - // Close the buffer - in.close(); - } - return bytes; - } -} \ No newline at end of file diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/net/PasswordAuthenticator.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/net/PasswordAuthenticator.java deleted file mode 100755 index 81c68f66..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/net/PasswordAuthenticator.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.net; - -import java.net.*; - -/** - * Interface fro PasswordAuthenticators used by SimpleAuthenticator. - * - * @see SimpleAuthenticator - * @see java.net.Authenticator - * - * @author Harald Kuhr - * - * @version 1.0 - */ -public interface PasswordAuthenticator { - public PasswordAuthentication requestPasswordAuthentication(InetAddress addr, int port, String protocol, String prompt, String scheme); -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/net/SimpleAuthenticator.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/net/SimpleAuthenticator.java deleted file mode 100755 index a7830581..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/net/SimpleAuthenticator.java +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.net; - -import com.twelvemonkeys.lang.Validate; - -import java.net.Authenticator; -import java.net.InetAddress; -import java.net.PasswordAuthentication; -import java.net.URL; -import java.util.HashMap; -import java.util.Map; - -/** - * A simple Authenticator implementation. - * Singleton class, obtain reference through the static - * {@code getInstance} method. - *

- * After swearing, sweating, pulling my hair, banging my head repeatedly - * into the walls and reading the java.net.Authenticator API documentation - * once more, an idea came to my mind. This is the result. I hope you find it - * useful. -- Harald K. - * - * @author Harald Kuhr - * @version 1.0 - * @see java.net.Authenticator - */ -public class SimpleAuthenticator extends Authenticator { - /** The reference to the single instance of this class. */ - private static SimpleAuthenticator sInstance = null; - /** Keeps track of the state of this class. */ - private static boolean sInitialized = false; - - // These are used for the identification hack. - private final static String MAGIC = "magic"; - private final static int FOURTYTWO = 42; - - /** Basic authentication scheme. */ - public final static String BASIC = "Basic"; - - /** The hastable that keeps track of the PasswordAuthentications. */ - protected Map passwordAuthentications = null; - - /** The hastable that keeps track of the Authenticators. */ - protected Map authenticators = null; - - /** Creates a SimpleAuthenticator. */ - private SimpleAuthenticator() { - passwordAuthentications = new HashMap(); - authenticators = new HashMap(); - } - - /** - * Gets the SimpleAuthenticator instance and registers it through the - * Authenticator.setDefault(). If there is no current instance - * of the SimpleAuthenticator in the VM, one is created. This method will - * try to figure out if the setDefault() succeeded (a hack), and will - * return null if it was not able to register the instance as default. - * - * @return The single instance of this class, or null, if another - * Authenticator is allready registered as default. - */ - public static synchronized SimpleAuthenticator getInstance() { - if (!sInitialized) { - // Create an instance - sInstance = new SimpleAuthenticator(); - - // Try to set default (this may quietly fail...) - Authenticator.setDefault(sInstance); - - // A hack to figure out if we really did set the authenticator - PasswordAuthentication pa = Authenticator.requestPasswordAuthentication(null, FOURTYTWO, null, null, MAGIC); - - // If this test returns false, we didn't succeed, so we set the - // instance back to null. - if (pa == null || !MAGIC.equals(pa.getUserName()) || !("" + FOURTYTWO).equals(new String(pa.getPassword()))) { - sInstance = null; - } - - // Done - sInitialized = true; - } - - return sInstance; - } - - /** - * Gets the PasswordAuthentication for the request. Called when password - * authorization is needed. - * - * @return The PasswordAuthentication collected from the user, or null if - * none is provided. - */ - protected PasswordAuthentication getPasswordAuthentication() { - // Don't worry, this is just a hack to figure out if we were able - // to set this Authenticator through the setDefault method. - if (!sInitialized && MAGIC.equals(getRequestingScheme()) && getRequestingPort() == FOURTYTWO) { - return new PasswordAuthentication(MAGIC, ("" + FOURTYTWO).toCharArray()); - } - /* - System.err.println("getPasswordAuthentication"); - System.err.println(getRequestingSite()); - System.err.println(getRequestingPort()); - System.err.println(getRequestingProtocol()); - System.err.println(getRequestingPrompt()); - System.err.println(getRequestingScheme()); - */ - - // TODO: - // Look for a more specific PasswordAuthenticatior before using - // Default: - // - // if (...) - // return pa.requestPasswordAuthentication(getRequestingSite(), - // getRequestingPort(), - // getRequestingProtocol(), - // getRequestingPrompt(), - // getRequestingScheme()); - - return passwordAuthentications.get(new AuthKey(getRequestingSite(), - getRequestingPort(), - getRequestingProtocol(), - getRequestingPrompt(), - getRequestingScheme())); - } - - /** Registers a PasswordAuthentication with a given URL address. */ - public PasswordAuthentication registerPasswordAuthentication(URL pURL, PasswordAuthentication pPA) { - return registerPasswordAuthentication(NetUtil.createInetAddressFromURL(pURL), - pURL.getPort(), - pURL.getProtocol(), - null, // Prompt/Realm - BASIC, - pPA); - } - - /** Registers a PasswordAuthentication with a given net address. */ - public PasswordAuthentication registerPasswordAuthentication(InetAddress pAddress, int pPort, String pProtocol, String pPrompt, String pScheme, PasswordAuthentication pPA) { - /* - System.err.println("registerPasswordAuthentication"); - System.err.println(pAddress); - System.err.println(pPort); - System.err.println(pProtocol); - System.err.println(pPrompt); - System.err.println(pScheme); - */ - - return passwordAuthentications.put(new AuthKey(pAddress, pPort, pProtocol, pPrompt, pScheme), pPA); - } - - /** Unregisters a PasswordAuthentication with a given URL address. */ - public PasswordAuthentication unregisterPasswordAuthentication(URL pURL) { - return unregisterPasswordAuthentication(NetUtil.createInetAddressFromURL(pURL), pURL.getPort(), pURL.getProtocol(), null, BASIC); - } - - /** Unregisters a PasswordAuthentication with a given net address. */ - public PasswordAuthentication unregisterPasswordAuthentication(InetAddress pAddress, int pPort, String pProtocol, String pPrompt, String pScheme) { - return passwordAuthentications.remove(new AuthKey(pAddress, pPort, pProtocol, pPrompt, pScheme)); - } - - /** - * TODO: Registers a PasswordAuthenticator that can answer authentication - * requests. - * - * @see PasswordAuthenticator - */ - public void registerPasswordAuthenticator(PasswordAuthenticator pPA, AuthenticatorFilter pFilter) { - authenticators.put(pPA, pFilter); - } - - /** - * TODO: Unregisters a PasswordAuthenticator that can answer authentication - * requests. - * - * @see PasswordAuthenticator - */ - public void unregisterPasswordAuthenticator(PasswordAuthenticator pPA) { - authenticators.remove(pPA); - } -} - -/** - * Utility class, used for caching the PasswordAuthentication objects. - * Everything but address may be null - */ -class AuthKey { - // TODO: Move this class to sandbox? - - InetAddress address = null; - int port = -1; - String protocol = null; - String prompt = null; - String scheme = null; - - AuthKey(InetAddress pAddress, int pPort, String pProtocol, String pPrompt, String pScheme) { - Validate.notNull(pAddress, "address"); - - address = pAddress; - port = pPort; - protocol = pProtocol; - prompt = pPrompt; - scheme = pScheme; - - // System.out.println("Created: " + this); - } - - /** Creates a string representation of this object. */ - - public String toString() { - return "AuthKey[" + address + ":" + port + "/" + protocol + " \"" + prompt + "\" (" + scheme + ")]"; - } - - public boolean equals(Object pObj) { - return (pObj instanceof AuthKey && equals((AuthKey) pObj)); - } - - // Ahem.. Breaks the rule from Object.equals(Object): - // It is transitive: for any reference values x, y, and z, if x.equals(y) - // returns true and y.equals(z) returns true, then x.equals(z) - // should return true. - - public boolean equals(AuthKey pKey) { - // Maybe allow nulls, and still be equal? - return (address.equals(pKey.address) - && (port == -1 - || pKey.port == -1 - || port == pKey.port) - && (protocol == null - || pKey.protocol == null - || protocol.equals(pKey.protocol)) - && (prompt == null - || pKey.prompt == null - || prompt.equals(pKey.prompt)) - && (scheme == null - || pKey.scheme == null - || scheme.equalsIgnoreCase(pKey.scheme))); - } - - public int hashCode() { - // There won't be too many pr address, will it? ;-) - return address.hashCode(); - } -} - diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/DatabaseConnection.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/DatabaseConnection.java deleted file mode 100755 index efb5b60f..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/DatabaseConnection.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.sql; - -import com.twelvemonkeys.lang.SystemUtil; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.util.Properties; - -/** - * A class that holds a JDBC Connection. The class can be configured by a - * properties file. However, the approach is rather lame, and only lets you - * configure one connection... - *

- * Tested with jConnect (Sybase), I-net Sprinta2000 (MS SQL) and Oracle. - *

- * @todo be able to register more drivers, trough properties and runtime - * @todo be able to register more connections, trough properties and runtime - *

- * Example properties file
- * # filename: com.twelvemonkeys.sql.DatabaseConnection.properties - * driver=com.inet.tds.TdsDriver - * url=jdbc:inetdae7:127.0.0.1:1433?database\=mydb - * user=scott - * password=tiger - * # What do you expect, really? - * logDebug=true - * - * @author Philippe Béal (phbe@iconmedialab.no) - * @author Harald Kuhr (haraldk@iconmedialab.no) - * @author last modified by $Author: haku $ - * - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-sandbox/src/main/java/com/twelvemonkeys/sql/DatabaseConnection.java#1 $ - * - * @todo Use org.apache.commons.logging instead of proprietary logging. - * - */ - -public class DatabaseConnection { - - // Default driver - public final static String DEFAULT_DRIVER = "NO_DRIVER"; - // Default URL - public final static String DEFAULT_URL = "NO_URL"; - - protected static String mDriver = null; - protected static String mUrl = null; - - // Default debug is true - // private static boolean debug = true; - - protected static Properties mConfig = null; - //protected static Log mLog = null; - protected static Log mLog = null; - - protected static boolean mInitialized = false; - - // Must be like this... - // http://www.javaworld.com/javaworld/jw-02-2001/jw-0209-double.html :-) - private static DatabaseConnection sInstance = new DatabaseConnection(); - - /** - * Creates the DatabaseConnection. - */ - - private DatabaseConnection() { - init(); - } - - /** - * Gets the single DatabaseConnection instance. - */ - - protected static DatabaseConnection getInstance() { - /* - if (sInstance == null) { - sInstance = new DatabaseConnection(); - sInstance.init(); - } - */ - return sInstance; - } - - /** - * Initializes the DatabaseConnection, called from the constructor. - * - * @exception IllegalStateException if an attempt to call init() is made - * after the instance is allready initialized. - */ - - protected synchronized void init() { - // Make sure init is executed only once! - if (mInitialized) { - throw new IllegalStateException("init() may only be called once!"); - } - - mInitialized = true; - - try { - mConfig = SystemUtil.loadProperties(DatabaseConnection.class); - } - catch (FileNotFoundException fnf) { - // Ignore - } - catch (IOException ioe) { - //LogFactory.getLog(getClass()).error("Caught IOException: ", ioe); - new Log(this).logError(ioe); - //ioe.printStackTrace(); - } - finally { - if (mConfig == null) { - mConfig = new Properties(); - } - } - - mLog = new Log(this, mConfig); - //mLog = LogFactory.getLog(getClass()); - // debug = new Boolean(config.getProperty("debug", "true")).booleanValue(); - // config.list(System.out); - - mDriver = mConfig.getProperty("driver", DEFAULT_DRIVER); - mUrl = mConfig.getProperty("url", DEFAULT_URL); - } - - /** - * Gets the default JDBC Connection. The connection is configured through - * the properties file. - * - * @return the default jdbc Connection - */ - - public static Connection getConnection() { - return getConnection(null, null, getInstance().mUrl); - } - - /** - * Gets a JDBC Connection with the given parameters. The connection is - * configured through the properties file. - * - * @param pUser the database user name - * @param pPassword the password of the database user - * @param pURL the url to connect to - * - * @return a jdbc Connection - */ - - public static Connection getConnection(String pUser, - String pPassword, - String pURL) { - return getInstance().getConnectionInstance(pUser, pPassword, pURL); - - } - - /** - * Gets a JDBC Connection with the given parameters. The connection is - * configured through the properties file. - * - * @param pUser the database user name - * @param pPassword the password of the database user - * @param pURL the url to connect to - * - * @return a jdbc Connection - */ - - protected Connection getConnectionInstance(String pUser, - String pPassword, - String pURL) { - Properties props = (Properties) mConfig.clone(); - - if (pUser != null) { - props.put("user", pUser); - } - if (pPassword != null) { - props.put("password", pPassword); - } - - // props.list(System.out); - - try { - // Load & register the JDBC Driver - if (!DEFAULT_DRIVER.equals(mDriver)) { - Class.forName(mDriver).newInstance(); - } - - Connection conn = DriverManager.getConnection(pURL, props); - - if (mLog.getLogDebug()) { - //if (mLog.isDebugEnabled()) { - DatabaseMetaData dma = conn.getMetaData(); - mLog.logDebug("Connected to " + dma.getURL()); - mLog.logDebug("Driver " + dma.getDriverName()); - mLog.logDebug("Version " + dma.getDriverVersion()); - - //mLog.debug("Connected to " + dma.getURL()); - //mLog.debug("Driver " + dma.getDriverName()); - //mLog.debug("Version " + dma.getDriverVersion()); - } - - return conn; - } - catch (Exception e) { - mLog.logError(e.getMessage()); - - // Get chained excpetions - if (e instanceof SQLException) { - SQLException sqle = (SQLException) e; - while ((sqle = sqle.getNextException()) != null) { - mLog.logWarning(sqle); - } - } - } - return null; - } - -} - diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/DatabaseProduct.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/DatabaseProduct.java deleted file mode 100755 index 63188ded..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/DatabaseProduct.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.sql; - -import java.io.Serializable; - -/** - * DatabaseProduct - *

- * - * @author Harald Kuhr - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-sandbox/src/main/java/com/twelvemonkeys/sql/DatabaseProduct.java#1 $ - */ -public final class DatabaseProduct implements Serializable { - private static final String UNKNOWN_NAME = "Unknown"; - private static final String GENERIC_NAME = "Generic"; - private static final String CACHE_NAME = "Caché"; - private static final String DB2_NAME = "DB2"; - private static final String MSSQL_NAME = "MSSQL"; - private static final String ORACLE_NAME = "Oracle"; - private static final String POSTGRESS_NAME = "PostgreSQL"; - private static final String SYBASE_NAME = "Sybase"; - - /*public*/ static final DatabaseProduct UNKNOWN = new DatabaseProduct(UNKNOWN_NAME); - public static final DatabaseProduct GENERIC = new DatabaseProduct(GENERIC_NAME); - public static final DatabaseProduct CACHE = new DatabaseProduct(CACHE_NAME); - public static final DatabaseProduct DB2 = new DatabaseProduct(DB2_NAME); - public static final DatabaseProduct MSSQL = new DatabaseProduct(MSSQL_NAME); - public static final DatabaseProduct ORACLE = new DatabaseProduct(ORACLE_NAME); - public static final DatabaseProduct POSTGRES = new DatabaseProduct(POSTGRESS_NAME); - public static final DatabaseProduct SYBASE = new DatabaseProduct(SYBASE_NAME); - - private static final DatabaseProduct[] VALUES = { - GENERIC, CACHE, DB2, MSSQL, ORACLE, POSTGRES, SYBASE, - }; - - private static int sNextOrdinal = -1; - private final int mOrdinal = sNextOrdinal++; - - private final String mKey; - - private DatabaseProduct(String pName) { - mKey = pName; - } - - static int enumSize() { - return sNextOrdinal; - } - - final int id() { - return mOrdinal; - } - - final String key() { - return mKey; - } - - public String toString() { - return mKey + " [id=" + mOrdinal+ "]"; - } - - /** - * Gets the {@code DatabaseProduct} known by the given name. - * - * @param pName - * @return the {@code DatabaseProduct} known by the given name - * @throws IllegalArgumentException if there's no such name - */ - public static DatabaseProduct resolve(String pName) { - if ("ANSI".equalsIgnoreCase(pName) || GENERIC_NAME.equalsIgnoreCase(pName)) { - return GENERIC; - } - else if ("Cache".equalsIgnoreCase(pName) || CACHE_NAME.equalsIgnoreCase(pName)) { - return CACHE; - } - else if (DB2_NAME.equalsIgnoreCase(pName)) { - return DB2; - } - else if (MSSQL_NAME.equalsIgnoreCase(pName)) { - return MSSQL; - } - else if (ORACLE_NAME.equalsIgnoreCase(pName)) { - return ORACLE; - } - else if ("Postgres".equalsIgnoreCase(pName) || POSTGRESS_NAME.equalsIgnoreCase(pName)) { - return POSTGRES; - } - else if (SYBASE_NAME.equalsIgnoreCase(pName)) { - return SYBASE; - } - else { - throw new IllegalArgumentException("Unknown database product \"" + pName - + "\", try any of the known products, or \"Generic\""); - } - } - - private Object readResolve() { - return VALUES[mOrdinal]; // Canonicalize - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/DatabaseReadable.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/DatabaseReadable.java deleted file mode 100755 index f966dc7b..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/DatabaseReadable.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.sql; - -import java.util.Hashtable; - -/** - * Interface for classes that is to be read from a database, using the - * ObjectReader class. - * - * @author Harald Kuhr (haraldk@iconmedialab.no) - * @author last modified by $Author: haku $ - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-sandbox/src/main/java/com/twelvemonkeys/sql/DatabaseReadable.java#1 $ - * - * @todo Use JDK logging instead of proprietary logging. - * - */ -public interface DatabaseReadable { - - /** - * Gets the unique identifier of this DatabaseReadable object. - * - * @return An object that uniqely identifies this DatabaseReadable. - */ - - public Object getId(); - - /** - * Sets the unique identifier of this DatabaseReadable object. - * - * @param id An object that uniqely identifies this DatabaseReadable. - */ - - public void setId(Object id); - - /** - * Gets the object to database mapping of this DatabaseReadable. - * - * @return A Hashtable cotaining the database mapping for this - * DatabaseReadable. - */ - - public Hashtable getMapping(); -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/JDBCHelper.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/JDBCHelper.java deleted file mode 100755 index e9847d7f..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/JDBCHelper.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.sql; - -/** - * AbstractHelper - *

- * - * @author Harald Kuhr - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-sandbox/src/main/java/com/twelvemonkeys/sql/JDBCHelper.java#1 $ - */ -public abstract class JDBCHelper { - - private static JDBCHelper[] sHelpers = new JDBCHelper[DatabaseProduct.enumSize()]; - - static { - DatabaseProduct product = DatabaseProduct.resolve(System.getProperty("com.twelvemonkeys.sql.databaseProduct", "Generic")); - sHelpers[0] = createInstance(product); - } - - private JDBCHelper() { - } - - private static JDBCHelper createInstance(DatabaseProduct pProduct) { - // Get database name - // Instantiate helper - if (pProduct == DatabaseProduct.GENERIC) { - return new GenericHelper(); - } - else if (pProduct == DatabaseProduct.CACHE) { - return new CacheHelper(); - } - else if (pProduct == DatabaseProduct.DB2) { - return new DB2Helper(); - } - else if (pProduct == DatabaseProduct.MSSQL) { - return new MSSQLHelper(); - } - else if (pProduct == DatabaseProduct.ORACLE) { - return new OracleHelper(); - } - else if (pProduct == DatabaseProduct.POSTGRES) { - return new PostgreSQLHelper(); - } - else if (pProduct == DatabaseProduct.SYBASE) { - return new SybaseHelper(); - } - else { - throw new IllegalArgumentException("Unknown database product, try any of the known products, or \"generic\""); - } - } - - public final static JDBCHelper getInstance() { - return sHelpers[0]; - } - - public final static JDBCHelper getInstance(DatabaseProduct pProuct) { - JDBCHelper helper = sHelpers[pProuct.id()]; - if (helper == null) { - // This is ok, iff sHelpers[pProuct] = helper is an atomic op... - synchronized (sHelpers) { - helper = sHelpers[pProuct.id()]; - if (helper == null) { - helper = createInstance(pProuct); - sHelpers[pProuct.id()] = helper; - } - } - } - return helper; - } - - // Abstract or ANSI SQL implementations of different stuff - - public String getDefaultDriverName() { - return ""; - } - - public String getDefaultURL() { - return "jdbc:{$DRIVER}://localhost:{$PORT}/{$DATABASE}"; - } - - // Vendor specific concrete implementations - - static class GenericHelper extends JDBCHelper { - // Nothing here - } - - static class CacheHelper extends JDBCHelper { - public String getDefaultDriverName() { - return "com.intersys.jdbc.CacheDriver"; - } - - public String getDefaultURL() { - return "jdbc:Cache://localhost:1972/{$DATABASE}"; - } - } - - static class DB2Helper extends JDBCHelper { - public String getDefaultDriverName() { - return "COM.ibm.db2.jdbc.net.DB2Driver"; - } - - public String getDefaultURL() { - return "jdbc:db2:{$DATABASE}"; - } - } - - static class MSSQLHelper extends JDBCHelper { - public String getDefaultDriverName() { - return "com.microsoft.jdbc.sqlserver.SQLServerDriver"; - } - - public String getDefaultURL() { - return "jdbc:microsoft:sqlserver://localhost:1433;databasename={$DATABASE};SelectMethod=cursor"; - } - } - - static class OracleHelper extends JDBCHelper { - public String getDefaultDriverName() { - return "oracle.jdbc.driver.OracleDriver"; - } - - public String getDefaultURL() { - return "jdbc:oracle:thin:@localhost:1521:{$DATABASE}"; - } - } - - static class PostgreSQLHelper extends JDBCHelper { - public String getDefaultDriverName() { - return "org.postgresql.Driver"; - } - - public String getDefaultURL() { - return "jdbc:postgresql://localhost/{$DATABASE}"; - } - } - - static class SybaseHelper extends JDBCHelper { - public String getDefaultDriverName() { - return "com.sybase.jdbc2.jdbc.SybDriver"; - } - - public String getDefaultURL() { - return "jdbc:sybase:Tds:localhost:4100/"; - } - } -} \ No newline at end of file diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/Log.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/Log.java deleted file mode 100755 index df7b51d2..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/Log.java +++ /dev/null @@ -1,673 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.sql; - - -import com.twelvemonkeys.lang.SystemUtil; - -import java.io.*; -import java.util.Date; -import java.util.Hashtable; -import java.util.Properties; - -/** - * Class used for logging. - * The class currently supports four levels of logging (debug, warning, error - * and info). - *

- * The class maintains a cahce of OutputStreams, to avoid more than one stream - * logging to a specific file. The class should also be thread safe, in that no - * more than one instance of the class can log to the same OuputStream. - *

- * - * WARNING: The uniqueness of logfiles is based on filenames alone, meaning - * "info.log" and "./info.log" will probably be treated as different files, - * and have different streams attatched to them. - * - *

- * - * WARNING: The cached OutputStreams can possibly be in error state or be - * closed without warning. Should be fixed in later versions! - * - * - * @author Harald Kuhr (haraldk@iconmedialab.no) - * @author last modified by $Author: haku $ - * - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-sandbox/src/main/java/com/twelvemonkeys/sql/Log.java#1 $ - * - * @deprecated Use the JDK java.util.logging for logging. - * This class is old and outdated, and is here only for compatibility. It will - * be removed from the library in later releases. - *

- * All new code are strongly encouraged to use the org.apache.commons.logging - * package for logging. - * - * @see java.util.logging.Logger - * - */ - -class Log { - private static Hashtable streamCache = new Hashtable(); - - static { - streamCache.put("System.out", System.out); - streamCache.put("System.err", System.err); - } - - private static Log globalLog = null; - - private String owner = null; - - private boolean logDebug = false; - private boolean logWarning = false; - private boolean logError = true; // Log errors! - private boolean logInfo = false; - - private PrintStream debugLog = null; - private PrintStream warningLog = null; - private PrintStream errorLog = null; - private PrintStream infoLog = null; - - /** - * Init global log - */ - - static { - Properties config = null; - try { - config = SystemUtil.loadProperties(Log.class); - } - catch (FileNotFoundException fnf) { - // That's okay. - } - catch (IOException ioe) { - // Not so good - log(System.err, "ERROR", Log.class.getName(), null, ioe); - } - - globalLog = new Log(new Log(), config); - - // Defaults - if (globalLog.debugLog == null) - globalLog.setDebugLog(System.out); - if (globalLog.warningLog == null) - globalLog.setWarningLog(System.err); - if (globalLog.errorLog == null) - globalLog.setErrorLog(System.err); - if (globalLog.infoLog == null) - globalLog.setInfoLog(System.out); - - // Info - globalLog.logDebug("Logging system started."); - log(globalLog.infoLog, "INFO", Log.class.getName(), - "Logging system started.", null); - } - - /** - * Internal use only - */ - - private Log() { - } - - /** - * Creates a log - */ - - public Log(Object owner) { - this.owner = owner.getClass().getName(); - } - - /** - * Creates a log - */ - - public Log(Object owner, Properties config) { - this(owner); - - if (config == null) - return; - - // Set logging levels - logDebug = new Boolean(config.getProperty("logDebug", - "false")).booleanValue(); - logWarning = new Boolean(config.getProperty("logWarning", - "false")).booleanValue(); - logError = new Boolean(config.getProperty("logError", - "true")).booleanValue(); - logInfo = new Boolean(config.getProperty("logInfo", - "true")).booleanValue(); - - // Set logging streams - String fileName; - try { - if ((fileName = config.getProperty("debugLog")) != null) - setDebugLog(fileName); - - if ((fileName = config.getProperty("warningLog")) != null) - setWarningLog(fileName); - - if ((fileName = config.getProperty("errorLog")) != null) - setErrorLog(fileName); - - if ((fileName = config.getProperty("infoLog")) != null) - setInfoLog(fileName); - } - catch (IOException ioe) { - if (errorLog == null) - setErrorLog(System.err); - logError("Could not create one or more logging streams! ", ioe); - } - } - - /** - * Checks if we log debug info - * - * @return True if logging - */ - - public boolean getLogDebug() { - return logDebug; - } - - /** - * Sets wheter we are to log debug info - * - * @param logDebug Boolean, true if we want to log debug info - */ - - public void setLogDebug(boolean logDebug) { - this.logDebug = logDebug; - } - - /** - * Checks if we globally log debug info - * - * @return True if global logging - */ - /* - public static boolean getGlobalDebug() { - return globalDebug; - } - */ - /** - * Sets wheter we are to globally log debug info - * - * @param logDebug Boolean, true if we want to globally log debug info - */ - /* - public static void setGlobalDebug(boolean globalDebug) { - Log.globalDebug = globalDebug; - } - /* - /** - * Sets the OutputStream we want to print to - * - * @param os The OutputStream we will use for logging - */ - - public void setDebugLog(OutputStream os) { - debugLog = new PrintStream(os, true); - } - - /** - * Sets the filename of the File we want to print to. Equivalent to - * setDebugLog(new FileOutputStream(fileName, true)) - * - * @param file The File we will use for logging - * @see #setDebugLog(OutputStream) - */ - - public void setDebugLog(String fileName) throws IOException { - setDebugLog(getStream(fileName)); - } - - /** - * Prints debug info to the current debugLog - * - * @param message The message to log - * @see #logDebug(String, Exception) - */ - - public void logDebug(String message) { - logDebug(message, null); - } - - /** - * Prints debug info to the current debugLog - * - * @param exception An Exception - * @see #logDebug(String, Exception) - */ - - public void logDebug(Exception exception) { - logDebug(null, exception); - } - - - /** - * Prints debug info to the current debugLog - * - * @param message The message to log - * @param exception An Exception - */ - - public void logDebug(String message, Exception exception) { - if (!(logDebug || globalLog.logDebug)) - return; - - if (debugLog != null) - log(debugLog, "DEBUG", owner, message, exception); - else - log(globalLog.debugLog, "DEBUG", owner, message, exception); - } - - // WARNING - - /** - * Checks if we log warning info - * - * @return True if logging - */ - - public boolean getLogWarning() { - return logWarning; - } - - /** - * Sets wheter we are to log warning info - * - * @param logWarning Boolean, true if we want to log warning info - */ - - public void setLogWarning(boolean logWarning) { - this.logWarning = logWarning; - } - - /** - * Checks if we globally log warning info - * - * @return True if global logging - */ - /* - public static boolean getGlobalWarning() { - return globalWarning; - } - */ - /** - * Sets wheter we are to globally log warning info - * - * @param logWarning Boolean, true if we want to globally log warning info - */ - /* - public static void setGlobalWarning(boolean globalWarning) { - Log.globalWarning = globalWarning; - } - */ - /** - * Sets the OutputStream we want to print to - * - * @param os The OutputStream we will use for logging - */ - - public void setWarningLog(OutputStream os) { - warningLog = new PrintStream(os, true); - } - - /** - * Sets the filename of the File we want to print to. Equivalent to - * setWarningLog(new FileOutputStream(fileName, true)) - * - * @param file The File we will use for logging - * @see #setWarningLog(OutputStream) - */ - - public void setWarningLog(String fileName) throws IOException { - setWarningLog(getStream(fileName)); - } - - /** - * Prints warning info to the current warningLog - * - * @param message The message to log - * @see #logWarning(String, Exception) - */ - - public void logWarning(String message) { - logWarning(message, null); - } - - /** - * Prints warning info to the current warningLog - * - * @param exception An Exception - * @see #logWarning(String, Exception) - */ - - public void logWarning(Exception exception) { - logWarning(null, exception); - } - - - /** - * Prints warning info to the current warningLog - * - * @param message The message to log - * @param exception An Exception - */ - - public void logWarning(String message, Exception exception) { - if (!(logWarning || globalLog.logWarning)) - return; - - if (warningLog != null) - log(warningLog, "WARNING", owner, message, exception); - else - log(globalLog.warningLog, "WARNING", owner, message, exception); - } - - // ERROR - - /** - * Checks if we log error info - * - * @return True if logging - */ - - public boolean getLogError() { - return logError; - } - - /** - * Sets wheter we are to log error info - * - * @param logError Boolean, true if we want to log error info - */ - - public void setLogError(boolean logError) { - this.logError = logError; - } - - /** - * Checks if we globally log error info - * - * @return True if global logging - */ - /* - public static boolean getGlobalError() { - return globalError; - } - */ - /** - * Sets wheter we are to globally log error info - * - * @param logError Boolean, true if we want to globally log error info - */ - /* - public static void setGlobalError(boolean globalError) { - Log.globalError = globalError; - } - */ - /** - * Sets the OutputStream we want to print to - * - * @param os The OutputStream we will use for logging - */ - - public void setErrorLog(OutputStream os) { - errorLog = new PrintStream(os, true); - } - - /** - * Sets the filename of the File we want to print to. Equivalent to - * setErrorLog(new FileOutputStream(fileName, true)) - * - * @param file The File we will use for logging - * @see #setErrorLog(OutputStream) - */ - - public void setErrorLog(String fileName) throws IOException { - setErrorLog(getStream(fileName)); - } - - /** - * Prints error info to the current errorLog - * - * @param message The message to log - * @see #logError(String, Exception) - */ - - public void logError(String message) { - logError(message, null); - } - - /** - * Prints error info to the current errorLog - * - * @param exception An Exception - * @see #logError(String, Exception) - */ - - public void logError(Exception exception) { - logError(null, exception); - } - - /** - * Prints error info to the current errorLog - * - * @param message The message to log - * @param exception An Exception - */ - - public void logError(String message, Exception exception) { - if (!(logError || globalLog.logError)) - return; - - if (errorLog != null) - log(errorLog, "ERROR", owner, message, exception); - else - log(globalLog.errorLog, "ERROR", owner, message, exception); - } - - // INFO - - /** - * Checks if we log info info - * - * @return True if logging - */ - - public boolean getLogInfo() { - return logInfo; - } - - /** - * Sets wheter we are to log info info - * - * @param logInfo Boolean, true if we want to log info info - */ - - public void setLogInfo(boolean logInfo) { - this.logInfo = logInfo; - } - - /** - * Checks if we globally log info info - * - * @return True if global logging - */ - /* - public static boolean getGlobalInfo() { - return globalInfo; - } - */ - /** - * Sets wheter we are to globally log info info - * - * @param logInfo Boolean, true if we want to globally log info info - */ - /* - public static void setGlobalInfo(boolean globalInfo) { - Log.globalInfo = globalInfo; - } - */ - /** - * Sets the OutputStream we want to print to - * - * @param os The OutputStream we will use for logging - */ - - public void setInfoLog(OutputStream os) { - infoLog = new PrintStream(os, true); - } - - /** - * Sets the filename of the File we want to print to. Equivalent to - * setInfoLog(new FileOutputStream(fileName, true)) - * - * @param file The File we will use for logging - * @see #setInfoLog(OutputStream) - */ - - public void setInfoLog(String fileName) throws IOException { - setInfoLog(getStream(fileName)); - } - - /** - * Prints info info to the current infoLog - * - * @param message The message to log - * @see #logInfo(String, Exception) - */ - - public void logInfo(String message) { - logInfo(message, null); - } - - /** - * Prints info info to the current infoLog - * - * @param exception An Exception - * @see #logInfo(String, Exception) - */ - - public void logInfo(Exception exception) { - logInfo(null, exception); - } - - /** - * Prints info info to the current infoLog - * - * @param message The message to log - * @param exception An Exception - */ - - public void logInfo(String message, Exception exception) { - if (!(logInfo || globalLog.logInfo)) - return; - - if (infoLog != null) - log(infoLog, "INFO", owner, message, exception); - else - log(globalLog.infoLog, "INFO", owner, message, exception); - } - - // LOG - - /** - * Internal method to get a named stream - */ - - private static OutputStream getStream(String name) throws IOException { - OutputStream os = null; - - synchronized (streamCache) { - if ((os = (OutputStream) streamCache.get(name)) != null) - return os; - - os = new FileOutputStream(name, true); - streamCache.put(name, os); - } - - return os; - } - - /** - * Internal log method - */ - - private static void log(PrintStream ps, String header, - String owner, String message, Exception ex) { - // Only allow one instance to print to the given stream. - synchronized (ps) { - // Create output stream for logging - LogStream logStream = new LogStream(ps); - - logStream.time = new Date(System.currentTimeMillis()); - logStream.header = header; - logStream.owner = owner; - - if (message != null) - logStream.println(message); - - if (ex != null) { - logStream.println(ex.getMessage()); - ex.printStackTrace(logStream); - } - } - } -} - -/** - * Utility class for logging. - * - * Minimal overloading of PrintStream - */ - -class LogStream extends PrintStream { - Date time = null; - String header = null; - String owner = null; - - public LogStream(OutputStream ps) { - super(ps); - } - - public void println(Object o) { - if (o == null) - println("null"); - else - println(o.toString()); - } - - public void println(String str) { - super.println("*** " + header + " (" + time + ", " + time.getTime() - + ") " + owner + ": " + str); - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/ObjectManager.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/ObjectManager.java deleted file mode 100755 index 70486f32..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/ObjectManager.java +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.sql; - - -import java.lang.reflect.*; -import java.util.*; -import java.sql.SQLException; -import java.sql.Connection; - -/* - Det vi trenger er en mapping mellom - - abstrakt navn/klasse/type/identifikator (tilsv. repository) - - java klasse - - selve mappingen av db kolonne/java property - - I tillegg en mapping mellom alle objektene som brukes i VM'en, og deres id'er - -*/ - -/** - * Under construction. - * - * @author Harald Kuhr (haraldk@iconmedialab.no), - * @version 0.5 - */ -public abstract class ObjectManager { - private ObjectReader mObjectReader = null; - - private WeakHashMap mLiveObjects = new WeakHashMap(); // object/id - - private Hashtable mTypes = new Hashtable(); // type name/java class - private Hashtable mMappings = new Hashtable(); // type name/mapping - - /** - * Creates an Object Manager with the default JDBC connection - */ - - public ObjectManager() { - this(DatabaseConnection.getConnection()); - } - - /** - * Creates an Object Manager with the given JDBC connection - */ - - public ObjectManager(Connection pConnection) { - mObjectReader = new ObjectReader(pConnection); - } - - - /** - * Gets the property/column mapping for a given type - */ - - protected Hashtable getMapping(String pType) { - return (Hashtable) mMappings.get(pType); - } - - /** - * Gets the class for a type - * - * @return The class for a type. If the type is not found, this method will - * throw an excpetion, and will never return null. - */ - - protected Class getType(String pType) { - Class cl = (Class) mTypes.get(pType); - - if (cl == null) { - // throw new NoSuchTypeException(); - } - - return cl; - } - - /** - * Gets a java object of the class for a given type. - */ - - protected Object getObject(String pType) - /*throws XxxException*/ { - // Get class - Class cl = getType(pType); - - // Return the new instance (requires empty public constructor) - try { - return cl.newInstance(); - } - catch (Exception e) { - // throw new XxxException(e); - throw new RuntimeException(e.getMessage()); - } - - // Can't happen - //return null; - } - - /** - * Gets a DatabaseReadable object that can be used for looking up the - * object properties from the database. - */ - - protected DatabaseReadable getDatabaseReadable(String pType) { - - return new DatabaseObject(getObject(pType), getMapping(pType)); - } - - /** - * Reads the object of the given type and with the given id from the - * database - */ - - // interface - public Object getObject(String pType, Object pId) - throws SQLException { - - // Create DatabaseReadable and set id - DatabaseObject dbObject = (DatabaseObject) getDatabaseReadable(pType); - dbObject.setId(pId); - - // Read it - dbObject = (DatabaseObject) mObjectReader.readObject(dbObject); - - // Return it - return dbObject.getObject(); - } - - /** - * Reads the objects of the given type and with the given ids from the - * database - */ - - // interface - public Object[] getObjects(String pType, Object[] pIds) - throws SQLException { - - // Create Vector to hold the result - Vector result = new Vector(pIds.length); - - // Loop through Id's and fetch one at a time (no good performance...) - for (int i = 0; i < pIds.length; i++) { - // Create DBObject, set id and read it - DatabaseObject dbObject = - (DatabaseObject) getDatabaseReadable(pType); - - dbObject.setId(pIds[i]); - dbObject = (DatabaseObject) mObjectReader.readObject(dbObject); - - // Add to result if not null - if (dbObject != null) { - result.add(dbObject.getObject()); - } - } - - // Create array of correct type, length equal to Vector - Class cl = getType(pType); - Object[] arr = (Object[]) Array.newInstance(cl, result.size()); - - // Return the vector as an array - return result.toArray(arr); - } - - /** - * Reads the objects of the given type and with the given properties from - * the database - */ - - // interface - public Object[] getObjects(String pType, Hashtable pWhere) - throws SQLException { - return mObjectReader.readObjects(getDatabaseReadable(pType), pWhere); - } - - /** - * Reads all objects of the given type from the database - */ - - // interface - public Object[] getObjects(String pType) - throws SQLException { - return mObjectReader.readObjects(getDatabaseReadable(pType)); - } - - // interface - public Object addObject(Object pObject) { - // get id... - - return pObject; - } - - // interface - public Object updateObject(Object pObject) { - // get id... - - return pObject; - } - - // interface - public abstract Object deleteObject(String pType, Object pId); - - // interface - public abstract Object deleteObject(Object pObject); - - // interface - public abstract Object createObject(String pType, Object pId); - - // interface - public abstract Object createObject(String pType); - -} - -/** - * Utility class for reading Objects from the database - */ - -class DatabaseObject implements DatabaseReadable { - Hashtable mMapping = null; - - Object mId = null; - Object mObject = null; - - public DatabaseObject(Object pObject, Hashtable pMapping) { - setObject(pObject); - setMapping(pMapping); - } - - public Object getId() { - return mId; - } - - public void setId(Object pId) { - mId = pId; - } - - public void setObject(Object pObject) { - mObject = pObject; - } - public Object getObject() { - return mObject; - } - - public void setMapping(Hashtable pMapping) { - mMapping = pMapping; - } - - public Hashtable getMapping() { - return mMapping; - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/ObjectMapper.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/ObjectMapper.java deleted file mode 100755 index a5922979..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/ObjectMapper.java +++ /dev/null @@ -1,663 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.sql; - -import com.twelvemonkeys.lang.*; - -import java.lang.reflect.*; - -// Single-type import, to avoid util.Date/sql.Date confusion -import java.util.Hashtable; -import java.util.Vector; -import java.util.Enumeration; -import java.util.StringTokenizer; - -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; - -/** - * A class for mapping JDBC ResultSet rows to Java objects. - * - * @see ObjectReader - * - * @author Harald Kuhr (haraldk@iconmedialab.no) - * @author last modified by $Author: haku $ - * - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-sandbox/src/main/java/com/twelvemonkeys/sql/ObjectMapper.java#1 $ - * - * @todo Use JDK logging instead of proprietary logging. - */ -public class ObjectMapper { - final static String DIRECTMAP = "direct"; - final static String OBJECTMAP = "object"; - final static String COLLECTIONMAP = "collection"; - final static String OBJCOLLMAP = "objectcollection"; - - Class mInstanceClass = null; - - Hashtable mMethods = null; - - Hashtable mColumnMap = null; - Hashtable mPropertiesMap = null; - - Hashtable mJoins = null; - - private Hashtable mTables = null; - private Vector mColumns = null; - - Hashtable mForeignKeys = null; - Hashtable mPrimaryKeys = null; - Hashtable mMapTypes = null; - Hashtable mClasses = null; - - String mPrimaryKey = null; - String mForeignKey = null; - String mIdentityJoin = null; - - Log mLog = null; - - /** - * Creates a new ObjectMapper for a DatabaseReadable - * - * @param obj An object of type DatabaseReadable - */ - - /* - public ObjectMapper(DatabaseReadable obj) { - this(obj.getClass(), obj.getMapping()); - } - */ - /** - * Creates a new ObjectMapper for any object, given a mapping - * - * @param objClass The class of the object(s) created by this OM - * @param mapping an Hashtable containing the mapping information - * for this OM - */ - - public ObjectMapper(Class pObjClass, Hashtable pMapping) { - mLog = new Log(this); - - mInstanceClass = pObjClass; - - mJoins = new Hashtable(); - mPropertiesMap = new Hashtable(); - mColumnMap = new Hashtable(); - - mClasses = new Hashtable(); - mMapTypes = new Hashtable(); - mForeignKeys = new Hashtable(); - mPrimaryKeys = new Hashtable(); - - // Unpack and store mapping information - for (Enumeration keys = pMapping.keys(); keys.hasMoreElements();) { - String key = (String) keys.nextElement(); - String value = (String) pMapping.get(key); - - int dotIdx = key.indexOf("."); - - if (dotIdx >= 0) { - if (key.equals(".primaryKey")) { - // Primary key - mPrimaryKey = (String) pMapping.get(value); - } - else if (key.equals(".foreignKey")) { - // Foreign key - mForeignKey = (String) pMapping.get(value); - } - else if (key.equals(".join")) { - // Identity join - mIdentityJoin = (String) pMapping.get(key); - } - else if (key.endsWith(".primaryKey")) { - // Primary key in joining table - mPrimaryKeys.put(key.substring(0, dotIdx), value); - } - else if (key.endsWith(".foreignKey")) { - // Foreign key - mForeignKeys.put(key.substring(0, dotIdx), value); - } - else if (key.endsWith(".join")) { - // Joins - mJoins.put(key.substring(0, dotIdx), value); - } - else if (key.endsWith(".mapType")) { - // Maptypes - value = value.toLowerCase(); - - if (value.equals(DIRECTMAP) || value.equals(OBJECTMAP) || - value.equals(COLLECTIONMAP) || - value.equals(OBJCOLLMAP)) { - mMapTypes.put(key.substring(0, dotIdx), value); - } - else { - mLog.logError("Illegal mapType: \"" + value + "\"! " - + "Legal types are: direct, object, " - + "collection and objectCollection."); - } - } - else if (key.endsWith(".class")) { - // Classes - try { - mClasses.put(key.substring(0, dotIdx), - Class.forName(value)); - } - catch (ClassNotFoundException e) { - mLog.logError(e); - //e.printStackTrace(); - } - } - else if (key.endsWith(".collection")) { - // TODO!! - } - } - else { - // Property to column mappings - mPropertiesMap.put(key, value); - mColumnMap.put(value.substring(value.lastIndexOf(".") + 1), - key); - } - } - - mMethods = new Hashtable(); - Method[] methods = mInstanceClass.getMethods(); - for (int i = 0; i < methods.length; i++) { - // Two methods CAN have same name... - mMethods.put(methods[i].getName(), methods[i]); - } - } - - public void setPrimaryKey(String pPrimaryKey) { - mPrimaryKey = pPrimaryKey; - } - - /** - * Gets the name of the property, that acts as the unique identifier for - * this ObjectMappers type. - * - * @return The name of the primary key property - */ - - public String getPrimaryKey() { - return mPrimaryKey; - } - - public String getForeignKey() { - return mForeignKey; - } - - /** - * Gets the join, that is needed to find this ObjectMappers type. - * - * @return The name of the primary key property - */ - - public String getIdentityJoin() { - return mIdentityJoin; - } - - Hashtable getPropertyMapping(String pProperty) { - Hashtable mapping = new Hashtable(); - - if (pProperty != null) { - // Property - if (mPropertiesMap.containsKey(pProperty)) - mapping.put("object", mPropertiesMap.get(pProperty)); - - // Primary key - if (mPrimaryKeys.containsKey(pProperty)) { - mapping.put(".primaryKey", "id"); - mapping.put("id", mPrimaryKeys.get(pProperty)); - } - - //Foreign key - if (mForeignKeys.containsKey(pProperty)) - mapping.put(".foreignKey", mPropertiesMap.get(mForeignKeys.get(pProperty))); - - // Join - if (mJoins.containsKey(pProperty)) - mapping.put(".join", mJoins.get(pProperty)); - - // mapType - mapping.put(".mapType", "object"); - } - - return mapping; - } - - - /** - * Gets the column for a given property. - * - * @param property The property - * @return The name of the matching database column, on the form - * table.column - */ - - public String getColumn(String pProperty) { - if (mPropertiesMap == null || pProperty == null) - return null; - return (String) mPropertiesMap.get(pProperty); - } - - /** - * Gets the table name for a given property. - * - * @param property The property - * @return The name of the matching database table. - */ - - public String getTable(String pProperty) { - String table = getColumn(pProperty); - - if (table != null) { - int dotIdx = 0; - if ((dotIdx = table.lastIndexOf(".")) >= 0) - table = table.substring(0, dotIdx); - else - return null; - } - - return table; - } - - /** - * Gets the property for a given database column. If the column incudes - * table qualifier, the table qualifier is removed. - * - * @param column The name of the column - * @return The name of the mathcing property - */ - - public String getProperty(String pColumn) { - if (mColumnMap == null || pColumn == null) - return null; - - String property = (String) mColumnMap.get(pColumn); - - int dotIdx = 0; - if (property == null && (dotIdx = pColumn.lastIndexOf(".")) >= 0) - property = (String) mColumnMap.get(pColumn.substring(dotIdx + 1)); - - return property; - } - - - /** - * Maps each row of the given result set to an object ot this OM's type. - * - * @param rs The ResultSet to process (map to objects) - * @return An array of objects (of this OM's class). If there are no rows - * in the ResultSet, an empty (zero-length) array will be returned. - */ - - public synchronized Object[] mapObjects(ResultSet pRSet) throws SQLException { - Vector result = new Vector(); - - ResultSetMetaData meta = pRSet.getMetaData(); - int cols = meta.getColumnCount(); - - // Get colum names - String[] colNames = new String[cols]; - for (int i = 0; i < cols; i++) { - colNames[i] = meta.getColumnName(i + 1); // JDBC cols start at 1... - - /* - System.out.println(meta.getColumnLabel(i + 1)); - System.out.println(meta.getColumnName(i + 1)); - System.out.println(meta.getColumnType(i + 1)); - System.out.println(meta.getColumnTypeName(i + 1)); - // System.out.println(meta.getTableName(i + 1)); - // System.out.println(meta.getCatalogName(i + 1)); - // System.out.println(meta.getSchemaName(i + 1)); - // Last three NOT IMPLEMENTED!! - */ - } - - // Loop through rows in resultset - while (pRSet.next()) { - Object obj = null; - - try { - obj = mInstanceClass.newInstance(); // Asserts empty constructor! - } - catch (IllegalAccessException iae) { - mLog.logError(iae); - // iae.printStackTrace(); - } - catch (InstantiationException ie) { - mLog.logError(ie); - // ie.printStackTrace(); - } - - // Read each colum from this row into object - for (int i = 0; i < cols; i++) { - - String property = (String) mColumnMap.get(colNames[i]); - - if (property != null) { - // This column is mapped to a property - mapColumnProperty(pRSet, i + 1, property, obj); - } - } - - // Add object to the result Vector - result.addElement(obj); - } - - return result.toArray((Object[]) Array.newInstance(mInstanceClass, - result.size())); - } - - /** - * Maps a ResultSet column (from the current ResultSet row) to a named - * property of an object, using reflection. - * - * @param rs The JDBC ResultSet - * @param index The column index to get the value from - * @param property The name of the property to set the value of - * @param obj The object to set the property to - */ - - void mapColumnProperty(ResultSet pRSet, int pIndex, String pProperty, - Object pObj) { - if (pRSet == null || pProperty == null || pObj == null) - throw new IllegalArgumentException("ResultSet, Property or Object" - + " arguments cannot be null!"); - if (pIndex <= 0) - throw new IllegalArgumentException("Index parameter must be > 0!"); - - String methodName = "set" + StringUtil.capitalize(pProperty); - Method setMethod = (Method) mMethods.get(methodName); - - if (setMethod == null) { - // No setMethod for this property - mLog.logError("No set method for property \"" - + pProperty + "\" in " + pObj.getClass() + "!"); - return; - } - - // System.err.println("DEBUG: setMethod=" + setMethod); - - Method getMethod = null; - - String type = ""; - try { - Class[] cl = {Integer.TYPE}; - type = setMethod.getParameterTypes()[0].getName(); - - type = type.substring(type.lastIndexOf(".") + 1); - - // There is no getInteger, use getInt instead - if (type.equals("Integer")) { - type = "int"; - } - - // System.err.println("DEBUG: type=" + type); - getMethod = pRSet.getClass(). - getMethod("get" + StringUtil.capitalize(type), cl); - } - catch (Exception e) { - mLog.logError("Can't find method \"get" - + StringUtil.capitalize(type) + "(int)\" " - + "(for class " + StringUtil.capitalize(type) - + ") in ResultSet", e); - - return; - } - - try { - // Get the data from the DB - // System.err.println("DEBUG: " + getMethod.getName() + "(" + (i + 1) + ")"); - - Object[] colIdx = {new Integer(pIndex)}; - Object[] arg = {getMethod.invoke(pRSet, colIdx)}; - - // Set it to the object - // System.err.println("DEBUG: " + setMethod.getName() + "(" + arg[0] + ")"); - setMethod.invoke(pObj, arg); - } - catch (InvocationTargetException ite) { - mLog.logError(ite); - // ite.printStackTrace(); - } - catch (IllegalAccessException iae) { - mLog.logError(iae); - // iae.printStackTrace(); - } - } - - /** - * Creates a SQL query string to get the primary keys for this - * ObjectMapper. - */ - - String buildIdentitySQL(String[] pKeys) { - mTables = new Hashtable(); - mColumns = new Vector(); - - // Get columns to select - mColumns.addElement(getPrimaryKey()); - - // Get tables to select (and join) from and their joins - tableJoins(null, false); - - for (int i = 0; i < pKeys.length; i++) { - tableJoins(getColumn(pKeys[i]), true); - } - - // All data read, build SQL query string - return "SELECT " + getPrimaryKey() + " " + buildFromClause() - + buildWhereClause(); - } - - /** - * Creates a SQL query string to get objects for this ObjectMapper. - */ - - public String buildSQL() { - mTables = new Hashtable(); - mColumns = new Vector(); - - String key = null; - for (Enumeration keys = mPropertiesMap.keys(); keys.hasMoreElements();) { - key = (String) keys.nextElement(); - - // Get columns to select - String column = (String) mPropertiesMap.get(key); - mColumns.addElement(column); - - tableJoins(column, false); - } - - // All data read, build SQL query string - return buildSelectClause() + buildFromClause() - + buildWhereClause(); - } - - /** - * Builds a SQL SELECT clause from the columns Vector - */ - - private String buildSelectClause() { - StringBuilder sqlBuf = new StringBuilder(); - - sqlBuf.append("SELECT "); - - String column = null; - for (Enumeration select = mColumns.elements(); select.hasMoreElements();) { - column = (String) select.nextElement(); - - /* - String subColumn = column.substring(column.indexOf(".") + 1); - // System.err.println("DEBUG: col=" + subColumn); - String mapType = (String) mMapTypes.get(mColumnMap.get(subColumn)); - */ - String mapType = (String) mMapTypes.get(getProperty(column)); - - if (mapType == null || mapType.equals(DIRECTMAP)) { - sqlBuf.append(column); - - sqlBuf.append(select.hasMoreElements() ? ", " : " "); - } - } - - return sqlBuf.toString(); - } - - /** - * Builds a SQL FROM clause from the tables/joins Hashtable - */ - - private String buildFromClause() { - StringBuilder sqlBuf = new StringBuilder(); - - sqlBuf.append("FROM "); - - String table = null; - String schema = null; - for (Enumeration from = mTables.keys(); from.hasMoreElements();) { - table = (String) from.nextElement(); - /* - schema = (String) schemas.get(table); - - if (schema != null) - sqlBuf.append(schema + "."); - */ - - sqlBuf.append(table); - sqlBuf.append(from.hasMoreElements() ? ", " : " "); - } - - return sqlBuf.toString(); - } - - /** - * Builds a SQL WHERE clause from the tables/joins Hashtable - * - * @return Currently, this metod will return "WHERE 1 = 1", if no other - * WHERE conditions are specified. This can be considered a hack. - */ - - private String buildWhereClause() { - - StringBuilder sqlBuf = new StringBuilder(); - - String join = null; - boolean first = true; - - for (Enumeration where = mTables.elements(); where.hasMoreElements();) { - join = (String) where.nextElement(); - - if (join.length() > 0) { - if (first) { - // Skip " AND " in first iteration - first = false; - } - else { - sqlBuf.append(" AND "); - } - } - - sqlBuf.append(join); - } - - if (sqlBuf.length() > 0) - return "WHERE " + sqlBuf.toString(); - - return "WHERE 1 = 1"; // Hacky... - } - - /** - * Finds tables used in mappings and joins and adds them to the tables - * Hashtable, with the table name as key, and the join as value. - */ - - private void tableJoins(String pColumn, boolean pWhereJoin) { - String join = null; - String table = null; - - if (pColumn == null) { - // Identity - join = getIdentityJoin(); - table = getTable(getProperty(getPrimaryKey())); - } - else { - // Normal - int dotIndex = -1; - if ((dotIndex = pColumn.lastIndexOf(".")) <= 0) { - // No table qualifier - return; - } - - // Get table qualifier. - table = pColumn.substring(0, dotIndex); - - // Don't care about the tables that are not supposed to be selected from - String property = (String) getProperty(pColumn); - - if (property != null) { - String mapType = (String) mMapTypes.get(property); - if (!pWhereJoin && mapType != null && !mapType.equals(DIRECTMAP)) { - return; - } - - join = (String) mJoins.get(property); - } - } - - // If table is not in the tables Hash, add it, and check for joins. - if (mTables.get(table) == null) { - if (join != null) { - mTables.put(table, join); - - StringTokenizer tok = new StringTokenizer(join, "= "); - String next = null; - - while(tok.hasMoreElements()) { - next = tok.nextToken(); - // Don't care about SQL keywords - if (next.equals("AND") || next.equals("OR") - || next.equals("NOT") || next.equals("IN")) { - continue; - } - // Check for new tables and joins in this join clause. - tableJoins(next, false); - } - } - else { - // No joins for this table. - join = ""; - mTables.put(table, join); - } - } - } - -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/ObjectReader.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/ObjectReader.java deleted file mode 100755 index ffaf8a16..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/ObjectReader.java +++ /dev/null @@ -1,879 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.sql; - - -import com.twelvemonkeys.lang.StringUtil; -import com.twelvemonkeys.lang.SystemUtil; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.lang.reflect.Array; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.math.BigDecimal; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Properties; -import java.util.Vector; - -/** - * Class used for reading table data from a database through JDBC, and map - * the data to Java classes. - * - * @see ObjectMapper - * - * @author Harald Kuhr (haraldk@iconmedialab.no) - * @author last modified by $Author: haku $ - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-sandbox/src/main/java/com/twelvemonkeys/sql/ObjectReader.java#1 $ - * - * @todo Use JDK logging instead of proprietary logging. - * - */ -public class ObjectReader { - - /** - * Main method, for testing purposes only. - */ - - public final static void main(String[] pArgs) throws SQLException { - /* - System.err.println("Testing only!"); - - // Get default connection - ObjectReader obr = new ObjectReader(DatabaseConnection.getConnection()); - - com.twelvemonkeys.usedcars.DBCar car = new com.twelvemonkeys.usedcars.DBCar(new Integer(1)); - com.twelvemonkeys.usedcars.DBDealer dealer = new com.twelvemonkeys.usedcars.DBDealer("NO4537"); - - System.out.println(obr.readObject(dealer)); - com.twelvemonkeys.usedcars.Dealer[] dealers = (com.twelvemonkeys.usedcars.Dealer[]) obr.readObjects(dealer); - - for (int i = 0; i < dealers.length; i++) { - System.out.println(dealers[i]); - } - - System.out.println("------------------------------------------------------------------------------\n" - + "Total: " + dealers.length + " dealers in database\n"); - - Hashtable where = new Hashtable(); - - where.put("zipCode", "0655"); - dealers = (com.twelvemonkeys.usedcars.Dealer[]) obr.readObjects(dealer, where); - - for (int i = 0; i < dealers.length; i++) { - System.out.println(dealers[i]); - } - - System.out.println("------------------------------------------------------------------------------\n" - + "Total: " + dealers.length + " dealers matching query: " - + where + "\n"); - - - com.twelvemonkeys.usedcars.Car[] cars = null; - cars = (com.twelvemonkeys.usedcars.Car[]) obr.readObjects(car); - - for (int i = 0; i < cars.length; i++) { - System.out.println(cars[i]); - } - - System.out.println("------------------------------------------------------------------------------\n" - + "Total: " + cars.length + " cars in database\n"); - - where = new Hashtable(); - where.put("year", new Integer(1995)); - cars = (com.twelvemonkeys.usedcars.Car[]) obr.readObjects(car, where); - - for (int i = 0; i < cars.length; i++) { - System.out.println(cars[i]); - } - - System.out.println("------------------------------------------------------------------------------\n" - + "Total: " + cars.length + " cars matching query: " - + where + " \n"); - - - where = new Hashtable(); - where.put("publishers", "Bilguiden"); - cars = (com.twelvemonkeys.usedcars.Car[]) obr.readObjects(car, where); - - for (int i = 0; i < cars.length; i++) { - System.out.println(cars[i]); - } - - System.out.println("------------------------------------------------------------------------------\n" - + "Total: " + cars.length + " cars matching query: " - + where + "\n"); - - System.out.println("==============================================================================\n" - + getStats()); - */ - } - - - protected Log mLog = null; - protected Properties mConfig = null; - - /** - * The connection used for all database operations executed by this - * ObjectReader. - */ - - Connection mConnection = null; - - /** - * The cache for this ObjectReader. - * Probably a source for memory leaks, as it has no size limitations. - */ - - private Hashtable mCache = new Hashtable(); - - /** - * Creates a new ObjectReader, using the given JDBC Connection. The - * Connection will be used for all database reads by this ObjectReader. - * - * @param connection A JDBC Connection - */ - - public ObjectReader(Connection pConnection) { - mConnection = pConnection; - - try { - mConfig = SystemUtil.loadProperties(getClass()); - } - catch (FileNotFoundException fnf) { - // Just go with defaults - } - catch (IOException ioe) { - new Log(this).logError(ioe); - } - - mLog = new Log(this, mConfig); - } - - /** - * Gets a string containing the stats for this ObjectReader. - * - * @return A string to display the stats. - */ - - public static String getStats() { - long total = sCacheHit + sCacheMiss + sCacheUn; - double hit = ((double) sCacheHit / (double) total) * 100.0; - double miss = ((double) sCacheMiss / (double) total) * 100.0; - double un = ((double) sCacheUn / (double) total) * 100.0; - - // Default locale - java.text.NumberFormat nf = java.text.NumberFormat.getInstance(); - - return "Total: " + total + " reads. " - + "Cache hits: " + sCacheHit + " (" + nf.format(hit) + "%), " - + "Cache misses: " + sCacheMiss + " (" + nf.format(miss) + "%), " - + "Unattempted: " + sCacheUn + " (" + nf.format(un) + "%) "; - } - - /** - * Get an array containing Objects of type objClass, with the - * identity values for the given class set. - */ - - private Object[] readIdentities(Class pObjClass, Hashtable pMapping, - Hashtable pWhere, ObjectMapper pOM) - throws SQLException { - sCacheUn++; - // Build SQL query string - if (pWhere == null) - pWhere = new Hashtable(); - - String[] keys = new String[pWhere.size()]; - int i = 0; - for (Enumeration en = pWhere.keys(); en.hasMoreElements(); i++) { - keys[i] = (String) en.nextElement(); - } - - // Get SQL for reading identity column - String sql = pOM.buildIdentitySQL(keys) - + buildWhereClause(keys, pMapping); - - // Log? - mLog.logDebug(sql + " (" + pWhere + ")"); - - // Prepare statement and set values - PreparedStatement statement = mConnection.prepareStatement(sql); - for (int j = 0; j < keys.length; j++) { - Object key = pWhere.get(keys[j]); - - if (key instanceof Integer) - statement.setInt(j + 1, ((Integer) key).intValue()); - else if (key instanceof BigDecimal) - statement.setBigDecimal(j + 1, (BigDecimal) key); - else - statement.setString(j + 1, key.toString()); - } - - // Execute query - ResultSet rs = null; - try { - rs = statement.executeQuery(); - } - catch (SQLException e) { - mLog.logError(sql + " (" + pWhere + ")", e); - throw e; - } - Vector result = new Vector(); - - // Map query to objects - while (rs.next()) { - Object obj = null; - - try { - obj = pObjClass.newInstance(); - } - catch (IllegalAccessException iae) { - iae.printStackTrace(); - } - catch (InstantiationException ie) { - ie.printStackTrace(); - } - - // Map it - pOM.mapColumnProperty(rs, 1, - pOM.getProperty(pOM.getPrimaryKey()), obj); - result.addElement(obj); - } - - // Return array of identifiers - return result.toArray((Object[]) Array.newInstance(pObjClass, - result.size())); - } - - - /** - * Reads one object implementing the DatabaseReadable interface from the - * database. - * - * @param readable A DatabaseReadable object - * @return The Object read, or null in no object is found - */ - - public Object readObject(DatabaseReadable pReadable) throws SQLException { - return readObject(pReadable.getId(), pReadable.getClass(), - pReadable.getMapping()); - } - - /** - * Reads the object with the given id from the database, using the given - * mapping. - * - * @param id An object uniquely identifying the object to read - * @param objClass The clas - * @return The Object read, or null in no object is found - */ - - public Object readObject(Object pId, Class pObjClass, Hashtable pMapping) - throws SQLException { - return readObject(pId, pObjClass, pMapping, null); - } - - /** - * Reads all the objects of the given type from the - * database. The object must implement the DatabaseReadable interface. - * - * @return An array of Objects, or an zero-length array if none was found - */ - - public Object[] readObjects(DatabaseReadable pReadable) - throws SQLException { - return readObjects(pReadable.getClass(), - pReadable.getMapping(), null); - } - - /** - * Sets the property value to an object using reflection - * - * @param obj The object to get a property from - * @param property The name of the property - * @param value The property value - * - */ - - private void setPropertyValue(Object pObj, String pProperty, - Object pValue) { - - Method m = null; - Class[] cl = {pValue.getClass()}; - - try { - //Util.setPropertyValue(pObj, pProperty, pValue); - - // Find method - m = pObj.getClass(). - getMethod("set" + StringUtil.capitalize(pProperty), cl); - // Invoke it - Object[] args = {pValue}; - m.invoke(pObj, args); - - } - catch (NoSuchMethodException e) { - e.printStackTrace(); - } - catch (IllegalAccessException iae) { - iae.printStackTrace(); - } - catch (InvocationTargetException ite) { - ite.printStackTrace(); - } - - } - - /** - * Gets the property value from an object using reflection - * - * @param obj The object to get a property from - * @param property The name of the property - * - * @return The property value as an Object - */ - - private Object getPropertyValue(Object pObj, String pProperty) { - - Method m = null; - Class[] cl = new Class[0]; - - try { - //return Util.getPropertyValue(pObj, pProperty); - - // Find method - m = pObj.getClass(). - getMethod("get" + StringUtil.capitalize(pProperty), - new Class[0]); - // Invoke it - Object result = m.invoke(pObj, new Object[0]); - return result; - - } - catch (NoSuchMethodException e) { - e.printStackTrace(); - } - catch (IllegalAccessException iae) { - iae.printStackTrace(); - } - catch (InvocationTargetException ite) { - ite.printStackTrace(); - } - return null; - } - - /** - * Reads and sets the child properties of the given parent object. - * - * @param parent The object to set the child obects to. - * @param om The ObjectMapper of the parent object. - */ - - private void setChildObjects(Object pParent, ObjectMapper pOM) - throws SQLException { - if (pOM == null) { - throw new NullPointerException("ObjectMapper in readChildObjects " - + "cannot be null!!"); - } - - for (Enumeration keys = pOM.mMapTypes.keys(); keys.hasMoreElements();) { - String property = (String) keys.nextElement(); - String mapType = (String) pOM.mMapTypes.get(property); - - if (property.length() <= 0 || mapType == null) { - continue; - } - - // Get the id of the parent - Object id = getPropertyValue(pParent, - pOM.getProperty(pOM.getPrimaryKey())); - - if (mapType.equals(ObjectMapper.OBJECTMAP)) { - // OBJECT Mapping - - // Get the class for this property - Class objectClass = (Class) pOM.mClasses.get(property); - - DatabaseReadable dbr = null; - try { - dbr = (DatabaseReadable) objectClass.newInstance(); - } - catch (Exception e) { - mLog.logError(e); - } - - /* - Properties mapping = readMapping(objectClass); - */ - - // Get property mapping for child object - if (pOM.mJoins.containsKey(property)) - // mapping.setProperty(".join", (String) pOM.joins.get(property)); - dbr.getMapping().put(".join", pOM.mJoins.get(property)); - - // Find id and put in where hash - Hashtable where = new Hashtable(); - - // String foreignKey = mapping.getProperty(".foreignKey"); - String foreignKey = (String) - dbr.getMapping().get(".foreignKey"); - - if (foreignKey != null) { - where.put(".foreignKey", id); - } - - Object[] child = readObjects(dbr, where); - // Object[] child = readObjects(objectClass, mapping, where); - - if (child.length < 1) - throw new SQLException("No child object with foreign key " - + foreignKey + "=" + id); - else if (child.length != 1) - throw new SQLException("More than one object with foreign " - + "key " + foreignKey + "=" + id); - - // Set child object to the parent - setPropertyValue(pParent, property, child[0]); - } - else if (mapType.equals(ObjectMapper.COLLECTIONMAP)) { - // COLLECTION Mapping - - // Get property mapping for child object - Hashtable mapping = pOM.getPropertyMapping(property); - - // Find id and put in where hash - Hashtable where = new Hashtable(); - String foreignKey = (String) mapping.get(".foreignKey"); - if (foreignKey != null) { - where.put(".foreignKey", id); - } - - DBObject dbr = new DBObject(); - dbr.mapping = mapping; // ugh... - // Read the objects - Object[] objs = readObjects(dbr, where); - - // Put the objects in a hash - Hashtable children = new Hashtable(); - for (int i = 0; i < objs.length; i++) { - children.put(((DBObject) objs[i]).getId(), - ((DBObject) objs[i]).getObject()); - } - - // Set child properties to parent object - setPropertyValue(pParent, property, children); - } - } - } - - /** - * Reads all objects from the database, using the given mapping. - * - * @param objClass The class of the objects to read - * @param mapping The hashtable containing the object mapping - * - * @return An array of Objects, or an zero-length array if none was found - */ - - public Object[] readObjects(Class pObjClass, Hashtable pMapping) - throws SQLException { - return readObjects(pObjClass, pMapping, null); - } - - /** - * Builds extra SQL WHERE clause - * - * @param keys An array of ID names - * @param mapping The hashtable containing the object mapping - * - * @return A string containing valid SQL - */ - - private String buildWhereClause(String[] pKeys, Hashtable pMapping) { - StringBuilder sqlBuf = new StringBuilder(); - - for (int i = 0; i < pKeys.length; i++) { - String column = (String) pMapping.get(pKeys[i]); - sqlBuf.append(" AND "); - sqlBuf.append(column); - sqlBuf.append(" = ?"); - } - - return sqlBuf.toString(); - - } - - private String buildIdInClause(Object[] pIds, Hashtable pMapping) { - StringBuilder sqlBuf = new StringBuilder(); - - if (pIds != null && pIds.length > 0) { - sqlBuf.append(" AND "); - sqlBuf.append(pMapping.get(".primaryKey")); - sqlBuf.append(" IN ("); - - for (int i = 0; i < pIds.length; i++) { - sqlBuf.append(pIds[i]); // SETTE INN '?' ??? - sqlBuf.append(", "); - } - sqlBuf.append(")"); - } - - return sqlBuf.toString(); - - } - - /** - * Reads all objects from the database, using the given mapping. - * - * @param readable A DatabaseReadable object - * @param mapping The hashtable containing the object mapping - * - * @return An array of Objects, or an zero-length array if none was found - */ - - public Object[] readObjects(DatabaseReadable pReadable, Hashtable pWhere) - throws SQLException { - return readObjects(pReadable.getClass(), - pReadable.getMapping(), pWhere); - } - - - /** - * Reads the object with the given id from the database, using the given - * mapping. - * This is the most general form of readObject(). - * - * @param id An object uniquely identifying the object to read - * @param objClass The class of the object to read - * @param mapping The hashtable containing the object mapping - * @param where An hashtable containing extra criteria for the read - * - * @return An array of Objects, or an zero-length array if none was found - */ - - public Object readObject(Object pId, Class pObjClass, - Hashtable pMapping, Hashtable pWhere) - throws SQLException { - ObjectMapper om = new ObjectMapper(pObjClass, pMapping); - return readObject0(pId, pObjClass, om, pWhere); - } - - public Object readObjects(Object[] pIds, Class pObjClass, - Hashtable pMapping, Hashtable pWhere) - throws SQLException { - ObjectMapper om = new ObjectMapper(pObjClass, pMapping); - return readObjects0(pIds, pObjClass, om, pWhere); - } - - /** - * Reads all objects from the database, using the given mapping. - * This is the most general form of readObjects(). - * - * @param objClass The class of the objects to read - * @param mapping The hashtable containing the object mapping - * @param where An hashtable containing extra criteria for the read - * - * @return An array of Objects, or an zero-length array if none was found - */ - - public Object[] readObjects(Class pObjClass, Hashtable pMapping, - Hashtable pWhere) throws SQLException { - return readObjects0(pObjClass, pMapping, pWhere); - } - - // readObjects implementation - - private Object[] readObjects0(Class pObjClass, Hashtable pMapping, - Hashtable pWhere) throws SQLException { - ObjectMapper om = new ObjectMapper(pObjClass, pMapping); - - Object[] ids = readIdentities(pObjClass, pMapping, pWhere, om); - - Object[] result = readObjects0(ids, pObjClass, om, pWhere); - - return result; - } - - private Object[] readObjects0(Object[] pIds, Class pObjClass, - ObjectMapper pOM, Hashtable pWhere) - throws SQLException { - Object[] result = new Object[pIds.length]; - - // Read each object from ID - for (int i = 0; i < pIds.length; i++) { - - // TODO: For better cahce efficiency/performance: - // - Read as many objects from cache as possible - // - Read all others in ONE query, and add to cache - /* - sCacheUn++; - // Build SQL query string - if (pWhere == null) - pWhere = new Hashtable(); - - String[] keys = new String[pWhere.size()]; - int i = 0; - for (Enumeration en = pWhere.keys(); en.hasMoreElements(); i++) { - keys[i] = (String) en.nextElement(); - } - - // Get SQL for reading identity column - String sql = pOM.buildSelectClause() + pOM.buildFromClause() + - + buildWhereClause(keys, pMapping) + buildIdInClause(pIds, pMapping); - - // Log? - mLog.logDebug(sql + " (" + pWhere + ")"); - - - // Log? - mLog.logDebug(sql + " (" + pWhere + ")"); - - PreparedStatement statement = null; - - // Execute query, and map columns/properties - try { - statement = mConnection.prepareStatement(sql); - - // Set keys - for (int j = 0; j < keys.length; j++) { - Object value = pWhere.get(keys[j]); - - if (value instanceof Integer) - statement.setInt(j + 1, ((Integer) value).intValue()); - else if (value instanceof BigDecimal) - statement.setBigDecimal(j + 1, (BigDecimal) value); - else - statement.setString(j + 1, value.toString()); - } - // Set ids - for (int j = 0; j < pIds.length; j++) { - Object id = pIds[i]; - - if (id instanceof Integer) - statement.setInt(j + 1, ((Integer) id).intValue()); - else if (id instanceof BigDecimal) - statement.setBigDecimal(j + 1, (BigDecimal) id); - else - statement.setString(j + 1, id.toString()); - } - - ResultSet rs = statement.executeQuery(); - - Object[] result = pOM.mapObjects(rs); - - // Set child objects and return - for (int i = 0; i < result.length; i++) { - // FOR THIS TO REALLY GET EFFECTIVE, WE NEED TO SET ALL - // CHILDREN IN ONE GO! - setChildObjects(result[i], pOM); - mContent.put(pOM.getPrimaryKey() + "=" + pId, result[0]); - - } - // Return result - return result[0]; - - } - */ - - Object id = getPropertyValue(result[i], - pOM.getProperty(pOM.getPrimaryKey())); - - result[i] = readObject0(id, pObjClass, pOM, null); - - } - - return result; - } - - // readObject implementation, used for ALL database reads - - static long sCacheHit; - static long sCacheMiss; - static long sCacheUn; - - private Object readObject0(Object pId, Class pObjClass, ObjectMapper pOM, - Hashtable pWhere) throws SQLException { - if (pId == null && pWhere == null) - throw new IllegalArgumentException("Either id or where argument" - + "must be non-null!"); - - // First check if object exists in cache - if (pId != null) { - Object o = mCache.get(pOM.getPrimaryKey() + "=" + pId); - if (o != null) { - sCacheHit++; - return o; - } - sCacheMiss++; - } - else { - sCacheUn++; - } - - // Create where hash - if (pWhere == null) - pWhere = new Hashtable(); - - // Make sure the ID is in the where hash - if (pId != null) - pWhere.put(pOM.getProperty(pOM.getPrimaryKey()), pId); - - String[] keys = new String[pWhere.size()]; - Enumeration en = pWhere.keys(); - for (int i = 0; en.hasMoreElements(); i++) { - keys[i] = (String) en.nextElement(); - } - - // Get SQL query string - String sql = pOM.buildSQL() + buildWhereClause(keys, pOM.mPropertiesMap); - - // Log? - mLog.logDebug(sql + " (" + pWhere + ")"); - - PreparedStatement statement = null; - - // Execute query, and map columns/properties - try { - statement = mConnection.prepareStatement(sql); - - for (int j = 0; j < keys.length; j++) { - Object value = pWhere.get(keys[j]); - - if (value instanceof Integer) - statement.setInt(j + 1, ((Integer) value).intValue()); - else if (value instanceof BigDecimal) - statement.setBigDecimal(j + 1, (BigDecimal) value); - else - statement.setString(j + 1, value.toString()); - } - - ResultSet rs = statement.executeQuery(); - - Object[] result = pOM.mapObjects(rs); - - // Set child objects and return - if (result.length == 1) { - setChildObjects(result[0], pOM); - mCache.put(pOM.getPrimaryKey() + "=" + pId, result[0]); - - // Return result - return result[0]; - } - // More than 1 is an error... - else if (result.length > 1) { - throw new SQLException("More than one object with primary key " - + pOM.getPrimaryKey() + "=" - + pWhere.get(pOM.getProperty(pOM.getPrimaryKey())) + "!"); - } - } - catch (SQLException e) { - mLog.logError(sql + " (" + pWhere + ")", e); - throw e; - } - finally { - try { - statement.close(); - } - catch (SQLException e) { - mLog.logError(e); - } - } - - return null; - } - - /** - * Utility method for reading a property mapping from a properties-file - * - */ - - public static Properties loadMapping(Class pClass) { - try { - return SystemUtil.loadProperties(pClass); - } - catch (FileNotFoundException fnf) { - // System.err... err... - System.err.println("ERROR: " + fnf.getMessage()); - } - catch (IOException ioe) { - ioe.printStackTrace(); - } - return new Properties(); - } - - /** - * @deprecated Use loadMapping(Class) instead - * @see #loadMapping(Class) - */ - - public static Properties readMapping(Class pClass) { - return loadMapping(pClass); - } - - -} - -/** - * Utility class - */ - -class DBObject implements DatabaseReadable { - Object id; - Object o; - static Hashtable mapping; // WHOA, STATIC!?!? - - public DBObject() { - } - - public void setId(Object id) { - this.id = id; - } - public Object getId() { - return id; - } - - public void setObject(Object o) { - this.o = o; - } - public Object getObject() { - return o; - } - - public Hashtable getMapping() { - return mapping; - } -} - - diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/SQLUtil.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/SQLUtil.java deleted file mode 100755 index 04052d71..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/SQLUtil.java +++ /dev/null @@ -1,396 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.sql; - -import com.twelvemonkeys.lang.StringUtil; - -import java.sql.*; -import java.io.*; -import java.util.Properties; - - -/** - * A class used to test a JDBC database connection. It can also be used as a - * really simple form of command line SQL interface, that passes all command - * line parameters to the database as plain SQL, and returns all rows to - * Sytem.out. Be aware that the wildcard character (*) is intercepted by - * the console, so you have to quote your string, or escape the wildcard - * character, otherwise you may get unpredictable results. - *

- * Exmaple use - *
- *

- * $ java -cp lib\jconn2.jar;build com.twelvemonkeys.sql.SQLUtil
- * -d com.sybase.jdbc2.jdbc.SybDriver -u "jdbc:sybase:Tds:10.248.136.42:6100"
- * -l scott -p tiger "SELECT * FROM emp"
- * Make sure sure to include the path to your JDBC driver in the java class - * path! - * - * @author Philippe Béal (phbe@iconmedialab.no) - * @author Harald Kuhr (haraldk@iconmedialab.no) - * @author last modified by $author: WMHAKUR $ - * @version $id: $ - * @see DatabaseConnection - */ -public class SQLUtil { - /** - * Method main - * - * @param pArgs - * @throws SQLException - * - * @todo Refactor the long and ugly main method... - * Consider: - extract method parserArgs(String[])::Properties (how do we - * get the rest of the arguments? getProperty("_ARGV")? - * Make the Properties/Map an argument and return int with last - * option index? - * - extract method getStatementReader(Properties) - */ - public static void main(String[] pArgs) throws SQLException, IOException { - String user = null; - String password = null; - String url = null; - String driver = null; - String configFileName = null; - String scriptFileName = null; - String scriptSQLDelim = "go"; - int argIdx = 0; - boolean errArgs = false; - - while ((argIdx < pArgs.length) && (pArgs[argIdx].charAt(0) == '-') && (pArgs[argIdx].length() >= 2)) { - if ((pArgs[argIdx].charAt(1) == 'l') || pArgs[argIdx].equals("--login")) { - argIdx++; - user = pArgs[argIdx++]; - } - else if ((pArgs[argIdx].charAt(1) == 'p') || pArgs[argIdx].equals("--password")) { - argIdx++; - password = pArgs[argIdx++]; - } - else if ((pArgs[argIdx].charAt(1) == 'u') || pArgs[argIdx].equals("--url")) { - argIdx++; - url = pArgs[argIdx++]; - } - else if ((pArgs[argIdx].charAt(1) == 'd') || pArgs[argIdx].equals("--driver")) { - argIdx++; - driver = pArgs[argIdx++]; - } - else if ((pArgs[argIdx].charAt(1) == 'c') || pArgs[argIdx].equals("--config")) { - argIdx++; - configFileName = pArgs[argIdx++]; - } - else if ((pArgs[argIdx].charAt(1) == 's') || pArgs[argIdx].equals("--script")) { - argIdx++; - scriptFileName = pArgs[argIdx++]; - } - else if ((pArgs[argIdx].charAt(1) == 'h') || pArgs[argIdx].equals("--help")) { - argIdx++; - errArgs = true; - } - else { - System.err.println("Unknown option \"" + pArgs[argIdx++] + "\""); - } - } - if (errArgs || (scriptFileName == null && (pArgs.length < (argIdx + 1)))) { - System.err.println("Usage: SQLUtil [--help|-h] [--login|-l ] [--password|-p ] [--driver|-d ] [--url|-u ] [--config|-c ] [--script|-s ] "); - System.exit(5); - } - - // If config file, read config and use as defaults - // NOTE: Command line options override! - if (!StringUtil.isEmpty(configFileName)) { - Properties config = new Properties(); - File configFile = new File(configFileName); - if (!configFile.exists()) { - System.err.println("Config file " + configFile.getAbsolutePath() + " does not exist."); - System.exit(10); - } - - InputStream in = new FileInputStream(configFile); - try { - config.load(in); - } - finally { - in.close(); - } - - if (driver == null) { - driver = config.getProperty("driver"); - } - if (url == null) { - url = config.getProperty("url"); - } - if (user == null) { - user = config.getProperty("login"); - } - if (password == null) { - password = config.getProperty("password"); - } - } - - // Register JDBC driver - if (driver != null) { - registerDriver(driver); - } - Connection conn = null; - - try { - // Use default connection from DatabaseConnection.properties - conn = DatabaseConnection.getConnection(user, password, url); - if (conn == null) { - System.err.println("No connection."); - System.exit(10); - } - - BufferedReader reader; - if (scriptFileName != null) { - // Read SQL from file - File file = new File(scriptFileName); - if (!file.exists()) { - System.err.println("Script file " + file.getAbsolutePath() + " does not exist."); - System.exit(10); - } - - reader = new BufferedReader(new FileReader(file)); - } - else { - // Create SQL statement from command line params - StringBuilder sql = new StringBuilder(); - for (int i = argIdx; i < pArgs.length; i++) { - sql.append(pArgs[i]).append(" "); - } - - reader = new BufferedReader(new StringReader(sql.toString())); - } - - //reader.mark(10000000); - //for (int i = 0; i < 5; i++) { - StringBuilder sql = new StringBuilder(); - while (true) { - // Read next line - String line = reader.readLine(); - if (line == null) { - // End of file, execute and quit - String str = sql.toString(); - if (!StringUtil.isEmpty(str)) { - executeSQL(str, conn); - } - break; - } - else if (line.trim().endsWith(scriptSQLDelim)) { - // End of statement, execute and continue - sql.append(line.substring(0, line.lastIndexOf(scriptSQLDelim))); - executeSQL(sql.toString(), conn); - sql.setLength(0); - } - else { - sql.append(line).append(" "); - } - } - //reader.reset(); - //} - } - finally { - // Close the connection - if (conn != null) { - conn.close(); - } - } - } - - private static void executeSQL(String pSQL, Connection pConn) throws SQLException { - System.out.println("Executing: " + pSQL); - - Statement stmt = null; - try { - // NOTE: Experimental - //stmt = pConn.prepareCall(pSQL); - //boolean results = ((CallableStatement) stmt).execute(); - - // Create statement and execute - stmt = pConn.createStatement(); - boolean results = stmt.execute(pSQL); - - int updateCount = -1; - - SQLWarning warning = stmt.getWarnings(); - while (warning != null) { - System.out.println("Warning: " + warning.getMessage()); - warning = warning.getNextWarning(); - } - - // More result sets to process? - while (results || (updateCount = stmt.getUpdateCount()) != -1) { - // INSERT, UPDATE or DELETE statement (no result set). - if (!results && (updateCount >= 0)) { - System.out.println("Operation successfull. " + updateCount + " row" + ((updateCount != 1) ? "s" : "") + " affected."); - System.out.println(); - } - // SELECT statement or stored procedure - else { - processResultSet(stmt.getResultSet()); - } - - // More results? - results = stmt.getMoreResults(); - } - } - catch (SQLException sqle) { - System.err.println("Error: " + sqle.getMessage()); - while ((sqle = sqle.getNextException()) != null) { - System.err.println(" " + sqle); - } - } - finally { - // Close the statement - if (stmt != null) { - stmt.close(); - } - } - } - - // TODO: Create interface ResultSetProcessor - // -- processWarnings(SQLWarning pWarnings); - // -- processMetaData(ResultSetMetaData pMetas); ?? - // -- processResultSet(ResultSet pResult); - // TODO: Add parameter pResultSetProcessor to method - // TODO: Extract contents of this method to class Default/CLIRSP - // TODO: Create new class JTableRSP that creates (?) and populates a JTable - // or a TableModel (?) - private static void processResultSet(ResultSet pResultSet) throws SQLException { - try { - // Get meta data - ResultSetMetaData meta = pResultSet.getMetaData(); - - // Print any warnings that might have occured - SQLWarning warning = pResultSet.getWarnings(); - while (warning != null) { - System.out.println("Warning: " + warning.getMessage()); - warning = warning.getNextWarning(); - } - - // Get the number of columns in the result set - int numCols = meta.getColumnCount(); - - for (int i = 1; i <= numCols; i++) { - boolean prepend = isNumeric(meta.getColumnType(i)); - - String label = maybePad(meta.getColumnLabel(i), meta.getColumnDisplaySize(i), " ", prepend); - - System.out.print(label + "\t"); - } - System.out.println(); - for (int i = 1; i <= numCols; i++) { - boolean prepend = isNumeric(meta.getColumnType(i)); - String label = maybePad("(" + meta.getColumnTypeName(i) + "/" + meta.getColumnClassName(i) + ")", meta.getColumnDisplaySize(i), " ", prepend); - System.out.print(label + "\t"); - } - System.out.println(); - for (int i = 1; i <= numCols; i++) { - String label = maybePad("", meta.getColumnDisplaySize(i), "-", false); - System.out.print(label + "\t"); - } - System.out.println(); - while (pResultSet.next()) { - for (int i = 1; i <= numCols; i++) { - boolean prepend = isNumeric(meta.getColumnType(i)); - String value = maybePad(String.valueOf(pResultSet.getString(i)), meta.getColumnDisplaySize(i), " ", prepend); - System.out.print(value + "\t"); - //System.out.print(pResultSet.getString(i) + "\t"); - } - System.out.println(); - } - System.out.println(); - } - catch (SQLException sqle) { - System.err.println("Error: " + sqle.getMessage()); - while ((sqle = sqle.getNextException()) != null) { - System.err.println(" " + sqle); - } - throw sqle; - } - finally { - if (pResultSet != null) { - pResultSet.close(); - } - } - } - - private static String maybePad(String pString, int pColumnDisplaySize, String pPad, boolean pPrepend) { - String padded; - if (pColumnDisplaySize < 100) { - padded = StringUtil.pad(pString, pColumnDisplaySize, pPad, pPrepend); - } - else { - padded = StringUtil.pad(pString, 100, pPad, pPrepend); - } - return padded; - } - - private static boolean isNumeric(int pColumnType) { - return (pColumnType == Types.INTEGER || pColumnType == Types.DECIMAL - || pColumnType == Types.TINYINT || pColumnType == Types.BIGINT - || pColumnType == Types.DOUBLE || pColumnType == Types.FLOAT - || pColumnType == Types.NUMERIC || pColumnType == Types.REAL - || pColumnType == Types.SMALLINT); - } - - public static boolean isDriverAvailable(String pDriver) { - //ClassLoader loader = Thread.currentThread().getContextClassLoader(); - try { - Class.forName(pDriver, false, null); // null means the caller's ClassLoader - return true; - } - catch (ClassNotFoundException ignore) { - // Ignore - } - return false; - } - - public static void registerDriver(String pDriver) { - // Register JDBC driver - try { - Class.forName(pDriver).newInstance(); - } - catch (ClassNotFoundException e) { - throw new RuntimeException("Driver class not found: " + e.getMessage(), e); - //System.err.println("Driver class not found: " + e.getMessage()); - //System.exit(5); - } - catch (InstantiationException e) { - throw new RuntimeException("Driver class could not be instantiated: " + e.getMessage(), e); - //System.err.println("Driver class could not be instantiated: " + e.getMessage()); - //System.exit(5); - } - catch (IllegalAccessException e) { - throw new RuntimeException("Driver class could not be instantiated: " + e.getMessage(), e); - //System.err.println("Driver class could not be instantiated: " + e.getMessage()); - //System.exit(5); - } - } -} \ No newline at end of file diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/package.html b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/package.html deleted file mode 100755 index 73bd0b1c..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/sql/package.html +++ /dev/null @@ -1,12 +0,0 @@ - - - -Provides classes for database access through JDBC. -The package contains warious mechanisms to et connections, read (currently) and write (future) objects from a database, etc. - -@see java.sql -@see com.twelvemonkeys.sql.ObjectReader -@see com.twelvemonkeys.sql.DatabaseConnection - - - diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/AbstractResource.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/AbstractResource.java deleted file mode 100755 index 39aa8937..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/AbstractResource.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.util; - -/** - * AbstractResource class description. - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/AbstractResource.java#1 $ - */ -abstract class AbstractResource implements Resource { - protected final Object resourceId; - protected final Object wrappedResource; - - /** - * Creates a {@code Resource}. - * - * @param pResourceId - * @param pWrappedResource - */ - protected AbstractResource(Object pResourceId, Object pWrappedResource) { - if (pResourceId == null) { - throw new IllegalArgumentException("id == null"); - } - if (pWrappedResource == null) { - throw new IllegalArgumentException("resource == null"); - } - - resourceId = pResourceId; - wrappedResource = pWrappedResource; - } - - public final Object getId() { - return resourceId; - } - - /** - * Default implementation simply returns {@code asURL().toExternalForm()}. - * - * @return a string representation of this resource - */ - public String toString() { - return asURL().toExternalForm(); - } - - /** - * Defautl implementation returns {@code mWrapped.hashCode()}. - * - * @return {@code mWrapped.hashCode()} - */ - public int hashCode() { - return wrappedResource.hashCode(); - } - - /** - * Default implementation - * - * @param pObject - * @return - */ - public boolean equals(Object pObject) { - return pObject instanceof AbstractResource - && wrappedResource.equals(((AbstractResource) pObject).wrappedResource); - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/BooleanKey.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/BooleanKey.java deleted file mode 100755 index b2eb177a..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/BooleanKey.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.util; - -import java.io.Serializable; - -/** - * BooleanKey class description. - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/BooleanKey.java#1 $ - */ -public class BooleanKey extends TypedMap.AbstractKey implements Serializable { - public BooleanKey() { - super(); - } - - public BooleanKey(String pName) { - super(pName); - } - - public boolean isCompatibleValue(Object pValue) { - return pValue instanceof Boolean; - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/DebugUtil.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/DebugUtil.java deleted file mode 100755 index 3d45d4e9..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/DebugUtil.java +++ /dev/null @@ -1,1757 +0,0 @@ -/**************************************************** - * * - * (c) 2000-2003 TwelveMonkeys * - * All rights reserved * - * http://www.twelvemonkeys.no * - * * - * $RCSfile: DebugUtil.java,v $ - * @version $Revision: #2 $ - * $Date: 2009/06/19 $ - * * - * @author Last modified by: $Author: haku $ - * * - ****************************************************/ - - - -/* - * Produced (p) 2002 TwelveMonkeys - * Address : Svovelstikka 1, Box 6432 Etterstad, 0605 Oslo, Norway. - * Phone : +47 22 57 70 00 - * Fax : +47 22 57 70 70 - */ -package com.twelvemonkeys.util; - - -import com.twelvemonkeys.lang.StringUtil; - -import java.io.PrintStream; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.text.DateFormat; -import java.util.*; - - -/** - * A utility class to simplify debugging. - * This includes viewing generic data structures, printing timestamps, printing object info and more... - * NB! Only use this class for instrumentation purposes - *

- * @author Eirik Torske - */ -@Deprecated -public class DebugUtil { - - // Constants - - /** Field PRINTSTREAM_IS_NULL_ERROR_MESSAGE */ - public static final String PRINTSTREAM_IS_NULL_ERROR_MESSAGE = "PrintStream is null"; - - /** Field OBJECT_IS_NULL_ERROR_MESSAGE */ - public static final String OBJECT_IS_NULL_ERROR_MESSAGE = "Object is null"; - - /** Field INTARRAY_IS_NULL_ERROR_MESSAGE */ - public static final String INTARRAY_IS_NULL_ERROR_MESSAGE = "int array is null"; - - /** Field STRINGARRAY_IS_NULL_ERROR_MESSAGE */ - public static final String STRINGARRAY_IS_NULL_ERROR_MESSAGE = "String array is null"; - - /** Field ENUMERATION_IS_NULL_ERROR_MESSAGE */ - public static final String ENUMERATION_IS_NULL_ERROR_MESSAGE = "Enumeration is null"; - - /** Field COLLECTION_IS_NULL_ERROR_MESSAGE */ - public static final String COLLECTION_IS_NULL_ERROR_MESSAGE = "Collection is null"; - - /** Field COLLECTION_IS_EMPTY_ERROR_MESSAGE */ - public static final String COLLECTION_IS_EMPTY_ERROR_MESSAGE = "Collection contains no elements"; - - /** Field MAP_IS_NULL_ERROR_MESSAGE */ - public static final String MAP_IS_NULL_ERROR_MESSAGE = "Map is null"; - - /** Field MAP_IS_EMPTY_ERROR_MESSAGE */ - public static final String MAP_IS_EMPTY_ERROR_MESSAGE = "Map contains no elements"; - - /** Field PROPERTIES_IS_NULL_ERROR_MESSAGE */ - public static final String PROPERTIES_IS_NULL_ERROR_MESSAGE = "Properties is null"; - - /** Field PROPERTIES_IS_EMPTY_ERROR_MESSAGE */ - public static final String PROPERTIES_IS_EMPTY_ERROR_MESSAGE = "Properties contains no elements"; - - /** Field CALENDAR_IS_NULL_ERROR_MESSAGE */ - public static final String CALENDAR_IS_NULL_ERROR_MESSAGE = "Calendar is null"; - - /** Field CALENDAR_CAUSATION_ERROR_MESSAGE */ - public static final String CALENDAR_CAUSATION_ERROR_MESSAGE = "The causation of the calendars is wrong"; - - /** Field TIMEDIFFERENCES_IS_NULL_ERROR_MESSAGE */ - public static final String TIMEDIFFERENCES_IS_NULL_ERROR_MESSAGE = "Inner TimeDifference object is null"; - - /** Field TIMEDIFFERENCES_WRONG_DATATYPE_ERROR_MESSAGE */ - public static final String TIMEDIFFERENCES_WRONG_DATATYPE_ERROR_MESSAGE = - "Element in TimeDifference collection is not a TimeDifference object"; - - /** Field DEBUG */ - public static final String DEBUG = "**** external debug: "; - - /** Field INFO */ - public static final String INFO = "**** external info: "; - - /** Field WARNING */ - public static final String WARNING = "**** external warning: "; - - /** Field ERROR */ - public static final String ERROR = "**** external error: "; - - /** - * Builds a prefix message to be used in front of info messages for identification purposes. - * The message format is: - *

-   * **** external info: [timestamp] [class name]:
-   * 
- *

- * @param pObject the {@code java.lang.Object} to be debugged. If the object ia a {@code java.lang.String} object, it is assumed that it is the class name given directly. - * @return a prefix for an info message. - */ - public static String getPrefixInfoMessage(final Object pObject) { - - StringBuilder buffer = new StringBuilder(); - - buffer.append(INFO); - buffer.append(getTimestamp()); - buffer.append(" "); - if (pObject == null) { - buffer.append("[unknown class]"); - } else { - if (pObject instanceof String) { - buffer.append((String) pObject); - } else { - buffer.append(getClassName(pObject)); - } - } - buffer.append(": "); - return buffer.toString(); - } - - /** - * Builds a prefix message to be used in front of debug messages for identification purposes. - * The message format is: - *

-   * **** external debug: [timestamp] [class name]:
-   * 
- *

- * @param pObject the {@code java.lang.Object} to be debugged. If the object ia a {@code java.lang.String} object, it is assumed that it is the class name given directly. - * @return a prefix for a debug message. - */ - public static String getPrefixDebugMessage(final Object pObject) { - - StringBuilder buffer = new StringBuilder(); - - buffer.append(DEBUG); - buffer.append(getTimestamp()); - buffer.append(" "); - if (pObject == null) { - buffer.append("[unknown class]"); - } else { - if (pObject instanceof String) { - buffer.append((String) pObject); - } else { - buffer.append(getClassName(pObject)); - } - } - buffer.append(": "); - return buffer.toString(); - } - - /** - * Builds a prefix message to be used in front of warning messages for identification purposes. - * The message format is: - *

-   * **** external warning: [timestamp] [class name]:
-   * 
- *

- * @param pObject the {@code java.lang.Object} to be debugged. If the object ia a {@code java.lang.String} object, it is assumed that it is the class name given directly. - * @return a prefix for a warning message. - */ - public static String getPrefixWarningMessage(final Object pObject) { - - StringBuilder buffer = new StringBuilder(); - - buffer.append(WARNING); - buffer.append(getTimestamp()); - buffer.append(" "); - if (pObject == null) { - buffer.append("[unknown class]"); - } else { - if (pObject instanceof String) { - buffer.append((String) pObject); - } else { - buffer.append(getClassName(pObject)); - } - } - buffer.append(": "); - return buffer.toString(); - } - - /** - * Builds a prefix message to be used in front of error messages for identification purposes. - * The message format is: - *

-   * **** external error: [timestamp] [class name]:
-   * 
- *

- * @param pObject the {@code java.lang.Object} to be debugged. If the object ia a {@code java.lang.String} object, it is assumed that it is the class name given directly. - * @return a prefix for an error message. - */ - public static String getPrefixErrorMessage(final Object pObject) { - - StringBuilder buffer = new StringBuilder(); - - buffer.append(ERROR); - buffer.append(getTimestamp()); - buffer.append(" "); - if (pObject == null) { - buffer.append("[unknown class]"); - } else { - if (pObject instanceof String) { - buffer.append((String) pObject); - } else { - buffer.append(getClassName(pObject)); - } - } - buffer.append(": "); - return buffer.toString(); - } - - /** - * The "default" method that invokes a given method of an object and prints the results to a {@code java.io.PrintStream}.
- * The method for invocation must have no formal parameters. If the invoking method does not exist, the {@code toString()} method is called. - * The {@code toString()} method of the returning object is called. - *

- * @param pObject the {@code java.lang.Object} to be printed. - * @param pMethodName a {@code java.lang.String} holding the name of the method to be invoked. - * @param pPrintStream the {@code java.io.PrintStream} for flushing the results. - */ - public static void printDebug(final Object pObject, final String pMethodName, final PrintStream pPrintStream) { - - if (pPrintStream == null) { - System.err.println(PRINTSTREAM_IS_NULL_ERROR_MESSAGE); - return; - } - if (pObject == null) { - pPrintStream.println(OBJECT_IS_NULL_ERROR_MESSAGE); - return; - } - if (!StringUtil.isEmpty(pMethodName)) { - try { - Method objectMethod = pObject.getClass().getMethod(pMethodName, null); - Object retVal = objectMethod.invoke(pObject, null); - - if (retVal != null) { - printDebug(retVal, null, pPrintStream); - } else { - throw new Exception(); - } - } catch (Exception e) { - - // Default - pPrintStream.println(pObject.toString()); - } - } else { // Ultimate default - pPrintStream.println(pObject.toString()); - } - } - - /** - * Prints the object's {@code toString()} method to a {@code java.io.PrintStream}. - *

- * @param pObject the {@code java.lang.Object} to be printed. - * @param pPrintStream the {@code java.io.PrintStream} for flushing the results. - */ - public static void printDebug(final Object pObject, final PrintStream pPrintStream) { - printDebug(pObject, null, pPrintStream); - } - - /** - * Prints the object's {@code toString()} method to {@code System.out}. - *

- * @param pObject the {@code java.lang.Object} to be printed. - */ - public static void printDebug(final Object pObject) { - printDebug(pObject, System.out); - } - - /** - * Prints a line break. - */ - public static void printDebug() { - System.out.println(); - } - - /** - * Prints a primitive {@code boolean} to {@code System.out}. - *

- * @param pBoolean the {@code boolean} to be printed. - */ - public static void printDebug(final boolean pBoolean) { - printDebug(new Boolean(pBoolean).toString()); - } - - /** - * Prints a primitive {@code int} to {@code System.out}. - *

- * - * @param pInt - */ - public static void printDebug(final int pInt) { - printDebug(new Integer(pInt).toString()); - } - - /** - * Prints the content of a {@code int[]} to a {@code java.io.PrintStream}. - *

- * @param pIntArray the {@code int[]} to be printed. - * @param pPrintStream the {@code java.io.PrintStream} for flushing the results. - */ - public static void printDebug(final int[] pIntArray, final PrintStream pPrintStream) { - - if (pPrintStream == null) { - System.err.println(PRINTSTREAM_IS_NULL_ERROR_MESSAGE); - return; - } - if (pIntArray == null) { - pPrintStream.println(INTARRAY_IS_NULL_ERROR_MESSAGE); - return; - } - for (int i = 0; i < pIntArray.length; i++) { - pPrintStream.println(pIntArray[i]); - } - } - - /** - * Prints the content of a {@code int[]} to {@code System.out}. - *

- * @param pIntArray the {@code int[]} to be printed. - */ - public static void printDebug(final int[] pIntArray) { - printDebug(pIntArray, System.out); - } - - /** - * Prints a number of character check methods from the {@code java.lang.Character} class to a {@code java.io.PrintStream}. - *

- * @param pChar the {@code java.lang.char} to be debugged. - * @param pPrintStream the {@code java.io.PrintStream} for flushing the results. - */ - public static void printDebug(final char pChar, final PrintStream pPrintStream) { - - if (pPrintStream == null) { - System.err.println(PRINTSTREAM_IS_NULL_ERROR_MESSAGE); - return; - } - pPrintStream.println("Character.getNumericValue(pChar): " + Character.getNumericValue(pChar)); - pPrintStream.println("Character.getType(pChar): " + Character.getType(pChar)); - pPrintStream.println("pChar.hashCode(): " + new Character(pChar).hashCode()); - pPrintStream.println("Character.isDefined(pChar): " + Character.isDefined(pChar)); - pPrintStream.println("Character.isDigit(pChar): " + Character.isDigit(pChar)); - pPrintStream.println("Character.isIdentifierIgnorable(pChar): " + Character.isIdentifierIgnorable(pChar)); - pPrintStream.println("Character.isISOControl(pChar): " + Character.isISOControl(pChar)); - pPrintStream.println("Character.isJavaIdentifierPart(pChar): " + Character.isJavaIdentifierPart(pChar)); - pPrintStream.println("Character.isJavaIdentifierStart(pChar): " + Character.isJavaIdentifierStart(pChar)); - pPrintStream.println("Character.isLetter(pChar): " + Character.isLetter(pChar)); - pPrintStream.println("Character.isLetterOrDigit(pChar): " + Character.isLetterOrDigit(pChar)); - pPrintStream.println("Character.isLowerCase(pChar): " + Character.isLowerCase(pChar)); - pPrintStream.println("Character.isSpaceChar(pChar): " + Character.isSpaceChar(pChar)); - pPrintStream.println("Character.isTitleCase(pChar): " + Character.isTitleCase(pChar)); - pPrintStream.println("Character.isUnicodeIdentifierPart(pChar): " + Character.isUnicodeIdentifierPart(pChar)); - pPrintStream.println("Character.isUnicodeIdentifierStart(pChar): " + Character.isUnicodeIdentifierStart(pChar)); - pPrintStream.println("Character.isUpperCase(pChar): " + Character.isUpperCase(pChar)); - pPrintStream.println("Character.isWhitespace(pChar): " + Character.isWhitespace(pChar)); - pPrintStream.println("pChar.toString(): " + new Character(pChar).toString()); - } - - /** - * Prints a number of character check methods from the {@code java.lang.Character} class to {@code System.out}. - *

- * @param pChar the {@code java.lang.char} to be debugged. - */ - public static void printDebug(final char pChar) { - printDebug(pChar, System.out); - } - - /** - * Prints the content of a {@code java.lang.String[]} to a {@code java.io.PrintStream}. - *

- * @param pStringArray the {@code java.lang.String[]} to be printed. - * @param pPrintStream the {@code java.io.PrintStream} for flushing the results. - */ - public static void printDebug(final String[] pStringArray, final PrintStream pPrintStream) { - - if (pPrintStream == null) { - System.err.println(PRINTSTREAM_IS_NULL_ERROR_MESSAGE); - return; - } - if (pStringArray == null) { - pPrintStream.println(STRINGARRAY_IS_NULL_ERROR_MESSAGE); - return; - } - for (int i = 0; i < pStringArray.length; i++) { - pPrintStream.println(pStringArray[i]); - } - } - - /** - * Prints the content of a {@code java.lang.String[]} to {@code System.out}. - *

- * @param pStringArray the {@code java.lang.String[]} to be printed. - */ - public static void printDebug(final String[] pStringArray) { - printDebug(pStringArray, System.out); - } - - /** - * Invokes a given method of every element in a {@code java.util.Enumeration} and prints the results to a {@code java.io.PrintStream}. - * The method to be invoked must have no formal parameters. - *

- * If an exception is throwed during the method invocation, the element's {@code toString()} method is called. - * For bulk data types, recursive invocations and invocations of other methods in this class, are used. - *

- * @param pEnumeration the {@code java.util.Enumeration} to be printed. - * @param pMethodName a {@code java.lang.String} holding the name of the method to be invoked on each collection element. - * @param pPrintStream the {@code java.io.PrintStream} for flushing the results. - * @see {@code java.util.Enumeration} - */ - public static void printDebug(final Enumeration pEnumeration, final String pMethodName, final PrintStream pPrintStream) { - - if (pPrintStream == null) { - System.err.println(PRINTSTREAM_IS_NULL_ERROR_MESSAGE); - return; - } - if (pEnumeration == null) { - pPrintStream.println(ENUMERATION_IS_NULL_ERROR_MESSAGE); - return; - } - while (pEnumeration.hasMoreElements()) { - printDebug(pEnumeration.nextElement(), pMethodName, pPrintStream); - } - } - - /** - * Invokes a given method of every element in a {@code java.util.Enumeration} and prints the results to a {@code java.io.PrintStream}. - * The method to be invoked must have no formal parameters. - *

- * If an exception is throwed during the method invocation, the element's {@code toString()} method is called. - * For bulk data types, recursive invocations and invocations of other methods in this class, are used. - *

- * @param pEnumeration the {@code java.util.Enumeration} to be printed. - * @param pMethodName a {@code java.lang.String} holding the name of the method to be invoked on each collection element. - * @see {@code java.util.Enumeration} - */ - public static void printDebug(final Enumeration pEnumeration, final String pMethodName) { - printDebug(pEnumeration, pMethodName, System.out); - } - - /** - * Invokes a given method of every element in a {@code java.util.Enumeration} and prints the results to a {@code java.io.PrintStream}. - * The method to be invoked must have no formal parameters. The default is calling an element's {@code toString()} method. - *

- * If an exception is throwed during the method invocation, the element's {@code toString()} method is called. - * For bulk data types, recursive invocations and invocations of other methods in this class, are used. - *

- * @param pEnumeration the {@code java.util.Enumeration} to be printed. - * @see {@code java.util.Enumeration} - */ - public static void printDebug(final Enumeration pEnumeration) { - printDebug(pEnumeration, null, System.out); - } - - /** - * Invokes a given method of every element in a {@code java.util.Collection} and prints the results to a {@code java.io.PrintStream}. - * The method to be invoked must have no formal parameters. - *

- * If an exception is throwed during the method invocation, the element's {@code toString()} method is called. - * For bulk data types, recursive invocations and invocations of other methods in this class, are used. - *

- * Be aware that the {@code Collection} interface embraces a large portion of the bulk data types in the {@code java.util} package, - * e.g. {@code List}, {@code Set}, {@code Vector} and {@code HashSet}. - *

- * For debugging of arrays, use the method {@code java.util.Arrays.asList(Object[])} method for converting the object array to a list before calling this method. - *

- * @param pCollection the {@code java.util.Collection} to be printed. - * @param pMethodName a {@code java.lang.String} holding the name of the method to be invoked on each collection element. - * @param pPrintStream the {@code java.io.PrintStream} for flushing the results. - * @see {@code java.util.Collection} - */ - public static void printDebug(final Collection pCollection, final String pMethodName, final PrintStream pPrintStream) { - - if (pPrintStream == null) { - System.err.println(PRINTSTREAM_IS_NULL_ERROR_MESSAGE); - return; - } - if (pCollection == null) { - pPrintStream.println(COLLECTION_IS_NULL_ERROR_MESSAGE); - return; - } else if (pCollection.isEmpty()) { - pPrintStream.println(COLLECTION_IS_EMPTY_ERROR_MESSAGE); - return; - } - for (Iterator i = pCollection.iterator(); i.hasNext(); ) { - printDebug(i.next(), pMethodName, pPrintStream); - } - } - - /** - * Invokes a given method of every element in a {@code java.util.Collection} and prints the results to {@code System.out}. - * The method to be invoked must have no formal parameters. - *

- * If an exception is throwed during the method invocation, the element's {@code toString()} method is called. - * For bulk data types, recursive invocations and invocations of other methods in this class, are used. - *

- * Be aware that the {@code Collection} interface embraces a large portion of the bulk data types in the {@code java.util} package, - * e.g. {@code List}, {@code Set}, {@code Vector} and {@code HashSet}. - *

- * For debugging of arrays, use the method {@code java.util.Arrays.asList(Object[])} method for converting the object array to a list before calling this method. - *

- * @param pCollection the {@code java.util.Collection} to be printed. - * @param pMethodName a {@code java.lang.String} holding the name of the method to be invoked on each collection element. - * @see {@code java.util.Collection} - */ - public static void printDebug(final Collection pCollection, final String pMethodName) { - printDebug(pCollection, pMethodName, System.out); - } - - /** - * Prints the content of a {@code java.util.Collection} to a {@code java.io.PrintStream}. - *

- * Not all data types are supported so far. The default is calling an element's {@code toString()} method. - * For bulk data types, recursive invocations and invocations of other methods in this class, are used. - *

- * Be aware that the {@code Collection} interface embraces a large portion of the bulk data types in the {@code java.util} package, - * e.g. {@code List}, {@code Set}, {@code Vector} and {@code HashSet}. - *

- * For debugging of arrays, use the method {@code java.util.Arrays.asList(Object[])} method for converting the object array to a list before calling this method. - *

- * @param pCollection the {@code java.util.Collection} to be printed. - * @param pPrintStream the {@code java.io.PrintStream} for flushing the results. - * @see {@code java.util.Collection} - */ - public static void printDebug(final Collection pCollection, final PrintStream pPrintStream) { - printDebug(pCollection, null, pPrintStream); - } - - /** - * Prints the content of a {@code java.util.Collection} to {@code System.out}. - *

- * Not all data types are supported so far. The default is calling an element's {@code toString()} method. - * For bulk data types, recursive invocations and invocations of other methods in this class, are used. - *

- * Be aware that the {@code Collection} interface embraces a large portion of the bulk data types in the {@code java.util} package, - * e.g. {@code List}, {@code Set}, {@code Vector} and {@code HashSet}. - *

- * For debugging of arrays, use the method {@code java.util.Arrays.asList(Object[])} method for converting the object array to a list before calling this method. - *

- * @param pCollection the {@code java.util.Collection} to be printed. - * @see {@code java.util.Collection} - */ - public static void printDebug(final Collection pCollection) { - printDebug(pCollection, System.out); - } - - /** - * Invokes a given method of every object in a {@code java.util.Map} and prints the results to a {@code java.io.PrintStream}. - * The method called must have no formal parameters. - *

- * If an exception is throwed during the method invocation, the element's {@code toString()} method is called. - * For bulk data types, recursive invocations and invocations of other methods in this class, are used. - *

- * @param pMap the {@code java.util.Map} to be printed. - * @param pMethodName a {@code java.lang.String} holding the name of the method to be invoked on each mapped object. - * @param pPrintStream the {@code java.io.PrintStream} for flushing the results. - * @see {@code java.util.Map} - */ - public static void printDebug(final Map pMap, final String pMethodName, final PrintStream pPrintStream) { - - if (pPrintStream == null) { - System.err.println(PRINTSTREAM_IS_NULL_ERROR_MESSAGE); - return; - } - if (pMap == null) { - pPrintStream.println(MAP_IS_NULL_ERROR_MESSAGE); - return; - } else if (pMap.isEmpty()) { - pPrintStream.println(MAP_IS_EMPTY_ERROR_MESSAGE); - return; - } - Object mKeyObject; - Object mEntryObject; - - for (Iterator i = pMap.keySet().iterator(); i.hasNext(); ) { - mKeyObject = i.next(); - mEntryObject = pMap.get(mKeyObject); - if ((mKeyObject instanceof String) && (mEntryObject instanceof String)) { - pPrintStream.println((String) mKeyObject + ": " + mEntryObject); - } else if ((mKeyObject instanceof String) && (mEntryObject instanceof List)) { - printDebug((List) mEntryObject, pPrintStream); - } else if ((mKeyObject instanceof String) && (mEntryObject instanceof Set)) { - printDebug((Set) mEntryObject, pPrintStream); - } else if (mKeyObject instanceof String) { - if (!StringUtil.isEmpty(pMethodName)) { - try { - Method objectMethod = mEntryObject.getClass().getMethod(pMethodName, null); - Object retVal = objectMethod.invoke(mEntryObject, null); - - if (retVal != null) { - pPrintStream.println((String) mKeyObject + ": " + retVal.toString()); - } else { // Default execution - throw new Exception(); - } - } catch (Exception e) { - - // Default - pPrintStream.println((String) mKeyObject + ": " + mEntryObject.toString()); - } - } else { // Default - pPrintStream.println((String) mKeyObject + ": " + mEntryObject.toString()); - } - } else if ((mKeyObject instanceof Integer) && (mEntryObject instanceof String)) { - pPrintStream.println((Integer) mKeyObject + ": " + mEntryObject); - } else if ((mKeyObject instanceof Integer) && (mEntryObject instanceof List)) { - printDebug((List) mEntryObject, pPrintStream); - } else if ((mKeyObject instanceof String) && (mEntryObject instanceof Set)) { - printDebug((Set) mEntryObject, pPrintStream); - } else if (mKeyObject instanceof Integer) { - if (!StringUtil.isEmpty(pMethodName)) { - try { - Method objectMethod = mEntryObject.getClass().getMethod(pMethodName, null); - Object retVal = objectMethod.invoke(mEntryObject, null); - - if (retVal != null) { - pPrintStream.println((Integer) mKeyObject + ": " + retVal.toString()); - } else { // Default execution - throw new Exception(); - } - } catch (Exception e) { - - // Default - pPrintStream.println((Integer) mKeyObject + ": " + mEntryObject.toString()); - } - } else { // Default - pPrintStream.println((Integer) mKeyObject + ": " + mEntryObject.toString()); - } - } - - // More.. - //else if - } - } - - /** - * Invokes a given method of every object in a {@code java.util.Map} to {@code System.out}. - * The method called must have no formal parameters. - *

- * If an exception is throwed during the method invocation, the element's {@code toString()} method is called.
- * For bulk data types, recursive invocations and invocations of other methods in this class, are used. - *

- * @param pMap the {@code java.util.Map} to be printed. - * @param pMethodName a {@code java.lang.String} holding the name of the method to be invoked on each mapped object. - * @see {@code java.util.Map} - */ - public static void printDebug(final Map pMap, final String pMethodName) { - printDebug(pMap, pMethodName, System.out); - } - - /** - * Prints the content of a {@code java.util.Map} to a {@code java.io.PrintStream}. - *

- * Not all data types are supported so far. The default is calling an element's {@code toString()} method.
- * For bulk data types, recursive invocations and invocations of other methods in this class, are used. - *

- * @param pMap the {@code java.util.Map} to be printed. - * @param pPrintStream the {@code java.io.PrintStream} for flushing the results. - * @see {@code java.util.Map} - */ - public static void printDebug(final Map pMap, final PrintStream pPrintStream) { - printDebug(pMap, null, pPrintStream); - } - - /** - * Prints the content of a {@code java.util.Map} to {@code System.out}. - *

- * Not all data types are supported so far. The default is calling an element's {@code toString()} method.
- * For bulk data types, recursive invocations and invocations of other methods in this class, are used. - *

- * @param pMap the {@code java.util.Map} to be printed. - * @see {@code java.util.Map} - */ - public static void printDebug(final Map pMap) { - printDebug(pMap, System.out); - } - - /** - * Prints the content of a {@code java.util.Properties} to a {@code java.io.PrintStream}. - *

- * @param pProperties the {@code java.util.Properties} to be printed. - * @param pPrintStream the {@code java.io.PrintStream} for flushing the results. - * @see {@code java.util.Properties} - */ - public static void printDebug(final Properties pProperties, final PrintStream pPrintStream) { - - if (pPrintStream == null) { - System.err.println(PRINTSTREAM_IS_NULL_ERROR_MESSAGE); - return; - } - if (pProperties == null) { - pPrintStream.println(PROPERTIES_IS_NULL_ERROR_MESSAGE); - return; - } else if (pProperties.isEmpty()) { - pPrintStream.println(PROPERTIES_IS_EMPTY_ERROR_MESSAGE); - return; - } - for (Enumeration e = pProperties.propertyNames(); e.hasMoreElements(); ) { - String key = (String) e.nextElement(); - - pPrintStream.println(key + ": " + pProperties.getProperty(key)); - } - } - - /** - * Prints the content of a {@code java.util.Properties} to {@code System.out}. - *

- * @param pProperties the {@code java.util.Properties} to be printed. - * @see {@code java.util.Properties} - */ - public static void printDebug(final Properties pProperties) { - printDebug(pProperties, System.out); - } - - // Timestamp utilities - - /** - * Prints out the calendar time. - *

- * @param pCalendar the {@code java.util.Calendar} object from which to extract the date information. - * @param pPrintStream the {@code java.io.PrintStream} for flushing the results. - * @see {@code java.util.Calendar} - */ - public static void printTimestamp(final Calendar pCalendar, final PrintStream pPrintStream) { - - if (pPrintStream == null) { - System.err.println(PRINTSTREAM_IS_NULL_ERROR_MESSAGE); - return; - } - pPrintStream.println(getTimestamp(pCalendar)); - } - - /** - * Prints out the system time. - *

- * @param pPrintStream the {@code java.io.PrintStream} for flushing the results. - * @see {@code java.util.GregorianCalendar} - */ - public static void printTimestamp(final PrintStream pPrintStream) { - - GregorianCalendar cal = new GregorianCalendar(); - - printTimestamp(cal, pPrintStream); - } - - /** - * Prints out the system time to {@code System.out}. - */ - public static void printTimestamp() { - printTimestamp(System.out); - } - - /** - * Returns a presentation of the date based on the given milliseconds. - *

- * @param pMilliseconds The specified number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT. - * @return a presentation of the calendar time. - * @see {@code java.util.Calendar} - */ - public static String getTimestamp(final String pMilliseconds) { - return getTimestamp(Long.parseLong(pMilliseconds)); - } - - /** - * Returns a presentation of the date based on the given milliseconds. - *

- * @param pMilliseconds The specified number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT. - * @return a presentation of the calendar time. - * @see {@code java.util.Calendar} - */ - public static String getTimestamp(final long pMilliseconds) { - - java.util.Date date = new java.util.Date(pMilliseconds); - java.util.Calendar calendar = new GregorianCalendar(); - - calendar.setTime(date); - return getTimestamp(calendar); - } - - /** - * Returns a presentation of the given calendar's time. - *

- * @param pCalendar the {@code java.util.Calendar} object from which to extract the date information. - * @return a presentation of the calendar time. - * @see {@code java.util.Calendar} - */ - public static String getTimestamp(final Calendar pCalendar) { - return buildTimestamp(pCalendar); - } - - /** - * @return a presentation of the system time. - */ - public static String getTimestamp() { - - GregorianCalendar cal = new GregorianCalendar(); - - return getTimestamp(cal); - } - - /** - * Builds a presentation of the given calendar's time. This method contains the common timestamp format used in this class. - * @return a presentation of the calendar time. - */ - protected static String buildTimestamp(final Calendar pCalendar) { - - if (pCalendar == null) { - return CALENDAR_IS_NULL_ERROR_MESSAGE; - } - - // The timestamp format - StringBuilder timestamp = new StringBuilder(); - - //timestamp.append(DateUtil.getMonthName(new Integer(pCalendar.get(Calendar.MONTH)).toString(), "0", "us", "MEDIUM", false) + " "); - timestamp.append(DateFormat.getDateInstance(DateFormat.MEDIUM).format(pCalendar.getTime())); - - //timestamp.append(pCalendar.get(Calendar.DAY_OF_MONTH) + " "); - timestamp.append(" "); - timestamp.append(StringUtil.pad(new Integer(pCalendar.get(Calendar.HOUR_OF_DAY)).toString(), 2, "0", true) + ":"); - timestamp.append(StringUtil.pad(new Integer(pCalendar.get(Calendar.MINUTE)).toString(), 2, "0", true) + ":"); - timestamp.append(StringUtil.pad(new Integer(pCalendar.get(Calendar.SECOND)).toString(), 2, "0", true) + ":"); - timestamp.append(StringUtil.pad(new Integer(pCalendar.get(Calendar.MILLISECOND)).toString(), 3, "0", true)); - return timestamp.toString(); - } - - /** - * Builds the time difference between two millisecond representations. - *

- * This method is to be used with small time intervals between 0 ms up to a couple of minutes. - *

- * @param pStartTime the start time. - * @param pEndTime the end time. - * @return the time difference in milliseconds. - */ - public static String buildTimeDifference(final long pStartTime, final long pEndTime) { - - //return pEndTime - pStartTime; - StringBuilder retVal = new StringBuilder(); - - // The time difference in milliseconds - long timeDifference = pEndTime - pStartTime; - - if (timeDifference < 1000) { - retVal.append(timeDifference); - retVal.append(" ms"); - } else { - long seconds = timeDifference / 1000; - - timeDifference = timeDifference % 1000; - retVal.append(seconds); - retVal.append("s "); - retVal.append(timeDifference); - retVal.append("ms"); - } - - //return retVal.toString() + " (original timeDifference: " + new String(new Long(pEndTime - pStartTime).toString()) + ")"; - return retVal.toString(); - } - - /** - * Builds the time difference between the given time and present time. - *

- * This method is to be used with small time intervals between 0 ms up to a couple of minutes. - *

- * @param pStartTime the start time. - * @return the time difference in milliseconds. - */ - public static String buildTimeDifference(final long pStartTime) { - - long presentTime = System.currentTimeMillis(); - - return buildTimeDifference(pStartTime, presentTime); - } - - /** - * Prints out the difference between two millisecond representations. - * The start time is subtracted from the end time. - *

- * @param pStartTime the start time. - * @param pEndTime the end time. - * @param pPrintStream the {@code java.io.PrintStream} for flushing the results. - */ - public static void printTimeDifference(final long pStartTime, final long pEndTime, final PrintStream pPrintStream) { - - if (pPrintStream == null) { - System.err.println(PRINTSTREAM_IS_NULL_ERROR_MESSAGE); - return; - } - pPrintStream.println(buildTimeDifference(pStartTime, pEndTime)); - } - - /** - * Prints out the difference between two millisecond representations. - * The start time is subtracted from the end time. - *

- * @param pStartTime the start time. - * @param pEndTime the end time. - */ - public static void printTimeDifference(final long pStartTime, final long pEndTime) { - printTimeDifference(pStartTime, pEndTime, System.out); - } - - /** - * Prints out the difference between the given time and present time. - * The start time is subtracted from the present time. - *

- * @param pStartTime the start time. - * @param pPrintStream the {@code java.io.PrintStream} for flushing the results. - */ - public static void printTimeDifference(final long pStartTime, final PrintStream pPrintStream) { - printTimeDifference(pStartTime, System.currentTimeMillis(), pPrintStream); - } - - /** - * Prints out the difference between the given time and present time to {@code System.out}. - * The start time is subtracted from the present time. - *

- * usage: - *

-   * long startTime = System.currentTimeMillis();
-   * ...
-   * com.iml.oslo.eito.util.DebugUtil.printTimeDifference(startTime);
-   * 
- *

- * @param pStartTime the start time. - */ - public static void printTimeDifference(final long pStartTime) { - printTimeDifference(pStartTime, System.out); - } - - /** - * Builds a string representing the difference between two calendar times. - * The first calendar object is subtracted from the second one. - *

- * This method is to be used with time intervals between 0 ms up to several hours. - *

- * @param pStartCalendar the first {@code java.util.Calendar}. - * @param pEndCalendar the second {@code java.util.Calendar}. - * @return a string representation of the time difference. - * @see {@code java.util.Calendar} - */ - public static String buildTimeDifference(final Calendar pStartCalendar, final Calendar pEndCalendar) { - - if (pStartCalendar == null) { - return CALENDAR_IS_NULL_ERROR_MESSAGE; - } - if (pEndCalendar == null) { - return CALENDAR_IS_NULL_ERROR_MESSAGE; - } - if (pEndCalendar.before(pStartCalendar)) { - return CALENDAR_CAUSATION_ERROR_MESSAGE; - } - int dateDiff = pEndCalendar.get(Calendar.DATE) - pStartCalendar.get(Calendar.DATE); - int hourDiff = pEndCalendar.get(Calendar.HOUR_OF_DAY) - pStartCalendar.get(Calendar.HOUR_OF_DAY); - int minuteDiff = pEndCalendar.get(Calendar.MINUTE) - pStartCalendar.get(Calendar.MINUTE); - int secondDiff = pEndCalendar.get(Calendar.SECOND) - pStartCalendar.get(Calendar.SECOND); - int milliSecondDiff = pEndCalendar.get(Calendar.MILLISECOND) - pStartCalendar.get(Calendar.MILLISECOND); - - if (milliSecondDiff < 0) { - secondDiff--; - milliSecondDiff += 1000; - } - if (secondDiff < 0) { - minuteDiff--; - secondDiff += 60; - } - if (minuteDiff < 0) { - hourDiff--; - minuteDiff += 60; - } - while (dateDiff > 0) { - dateDiff--; - hourDiff += 24; - } - - // Time difference presentation format - StringBuilder buffer = new StringBuilder(); - - if ((hourDiff == 0) && (minuteDiff == 0) && (secondDiff == 0)) { - buffer.append(milliSecondDiff); - buffer.append("ms"); - } else if ((hourDiff == 0) && (minuteDiff == 0)) { - buffer.append(secondDiff); - buffer.append("s "); - buffer.append(milliSecondDiff); - buffer.append("ms"); - } else if (hourDiff == 0) { - buffer.append(minuteDiff); - buffer.append("m "); - buffer.append(secondDiff); - buffer.append(","); - buffer.append(milliSecondDiff); - buffer.append("s"); - } else { - buffer.append(hourDiff); - buffer.append("h "); - buffer.append(minuteDiff); - buffer.append("m "); - buffer.append(secondDiff); - buffer.append(","); - buffer.append(milliSecondDiff); - buffer.append("s"); - } - return buffer.toString(); - } - - /** - * Prints out the difference between to calendar times. - * The first calendar object is subtracted from the second one. - *

- * @param pStartCalendar the first {@code java.util.Calendar}. - * @param pEndCalendar the second {@code java.util.Calendar}. - * @param pPrintStream the {@code java.io.PrintStream} for flushing the results. - * @see {@code java.util.Calendar} - */ - public static void printTimeDifference(final Calendar pStartCalendar, final Calendar pEndCalendar, final PrintStream pPrintStream) { - - if (pPrintStream == null) { - System.err.println(PRINTSTREAM_IS_NULL_ERROR_MESSAGE); - return; - } - pPrintStream.println(buildTimeDifference(pStartCalendar, pEndCalendar)); - } - - /** - * Prints out the difference between to calendar times two {@code System.out}. - * The first calendar object is subtracted from the second one. - *

- * @param pStartCalendar the first {@code java.util.Calendar}. - * @param pEndCalendar the second {@code java.util.Calendar}. - * @see {@code java.util.Calendar} - */ - public static void printTimeDifference(final Calendar pStartCalendar, final Calendar pEndCalendar) { - printTimeDifference(pStartCalendar, pEndCalendar, System.out); - } - - /** - * Prints out the difference between the given calendar time and present time. - *

- * @param pStartCalendar the {@code java.util.Calendar} to compare with present time. - * @param pPrintStream the {@code java.io.PrintStream} for flushing the results. - * @see {@code java.util.Calendar} - */ - public static void printTimeDifference(final Calendar pStartCalendar, final PrintStream pPrintStream) { - - GregorianCalendar endCalendar = new GregorianCalendar(); - - printTimeDifference(pStartCalendar, endCalendar, pPrintStream); - } - - /** - * Prints out the difference between the given calendar time and present time to {@code System.out}. - *

- * usage: - *

-   * GregorianCalendar startTime = new GregorianCalendar();
-   * ...
-   * com.iml.oslo.eito.util.DebugUtil.printTimeDifference(startTime);
-   * 
- *

- * @param pStartCalendar the {@code java.util.Calendar} to compare with present time. - * @see {@code java.util.Calendar} - */ - public static void printTimeDifference(final Calendar pStartCalendar) { - - GregorianCalendar endCalendar = new GregorianCalendar(); - - printTimeDifference(pStartCalendar, endCalendar); - } - - /** - * Prints out a {@code com.iml.oslo.eito.util.DebugUtil.TimeDifference} object. - *

- * @param pTimeDifference the {@code com.twelvemonkeys.util.DebugUtil.TimeDifference} to investigate. - * @param pPrintStream the {@code java.io.PrintStream} for flushing the results. - */ - public static void printTimeDifference(final TimeDifference pTimeDifference, final PrintStream pPrintStream) { - printTimeDifference(pTimeDifference.getStartCalendar(), pTimeDifference.getEndCalendar(), pPrintStream); - } - - /** - * Prints out a {@code com.iml.oslo.eito.util.DebugUtil.TimeDifference} object to {@code System.out}. - *

- * @param pTimeDifference the {@code com.twelvemonkeys.util.DebugUtil.TimeDifference} to investigate. - */ - public static void printTimeDifference(final TimeDifference pTimeDifference) { - printTimeDifference(pTimeDifference.getStartCalendar(), pTimeDifference.getEndCalendar(), System.out); - } - - /** - * A convenience class for embracing two {@code java.util.Calendar} objects. - * The class is used for building a collection of time differences according to the {@code printTimeAverage} method. - */ - public static class TimeDifference { - - Calendar mStartCalendar; - Calendar mEndCalendar; - - /** - * Constructor TimeDifference - * - * - */ - public TimeDifference() {} - - /** - * Constructor TimeDifference - * - * - * @param pStartCalendar - * @param pEndCalendar - * - */ - public TimeDifference(final Calendar pStartCalendar, final Calendar pEndCalendar) { - this.mStartCalendar = pStartCalendar; - this.mEndCalendar = pEndCalendar; - } - - /** - * Method setStartCalendar - * - * - * @param pStartCalendar - * - */ - public void setStartCalendar(Calendar pStartCalendar) { - this.mStartCalendar = pStartCalendar; - } - - /** - * Method getStartCalendar - * - * - * @return - * - */ - public Calendar getStartCalendar() { - return this.mStartCalendar; - } - - /** - * Method setEndCalendar - * - * - * @param pEndCalendar - * - */ - public void setEndCalendar(Calendar pEndCalendar) { - this.mEndCalendar = pEndCalendar; - } - - /** - * Method getEndCalendar - * - * - * @return - * - */ - public Calendar getEndCalendar() { - return this.mEndCalendar; - } - } - - /** - * Prints out the average time difference from a collection of {@code com.twelvemonkeys.util.DebugUtil.TimeDifference} objects. - *

- * - * @param pTimeDifferences - * @param pPrintStream the {@code java.io.PrintStream} for flushing the results. - */ - public static void printTimeAverage(final Collection pTimeDifferences, final PrintStream pPrintStream) { - - if (pPrintStream == null) { - System.err.println(PRINTSTREAM_IS_NULL_ERROR_MESSAGE); - return; - } - if (pTimeDifferences == null) { - pPrintStream.println(TIMEDIFFERENCES_IS_NULL_ERROR_MESSAGE); - return; - } - Object o; - TimeDifference timeDifference; - Calendar startCalendar = null; - Calendar endCalendar = null; - Calendar totalStartCalendar = null; - Calendar totalEndCalendar = null; - long startCalendarMilliSeconds, endCalendarMilliSeconds; - List timeDifferenceList = new Vector(); - Iterator i = pTimeDifferences.iterator(); - - if (i.hasNext()) { - o = i.next(); - if (!(o instanceof TimeDifference)) { - pPrintStream.println(TIMEDIFFERENCES_WRONG_DATATYPE_ERROR_MESSAGE); - return; - } - timeDifference = (TimeDifference) o; - startCalendar = timeDifference.getStartCalendar(); - totalStartCalendar = startCalendar; - endCalendar = timeDifference.getEndCalendar(); - startCalendarMilliSeconds = startCalendar.getTime().getTime(); - endCalendarMilliSeconds = endCalendar.getTime().getTime(); - timeDifferenceList.add(new Long(endCalendarMilliSeconds - startCalendarMilliSeconds)); - } - while (i.hasNext()) { - o = i.next(); - if (!(o instanceof TimeDifference)) { - pPrintStream.println(TIMEDIFFERENCES_WRONG_DATATYPE_ERROR_MESSAGE); - return; - } - timeDifference = (TimeDifference) o; - startCalendar = timeDifference.getStartCalendar(); - endCalendar = timeDifference.getEndCalendar(); - startCalendarMilliSeconds = startCalendar.getTime().getTime(); - endCalendarMilliSeconds = endCalendar.getTime().getTime(); - timeDifferenceList.add(new Long(endCalendarMilliSeconds - startCalendarMilliSeconds)); - } - totalEndCalendar = endCalendar; - int numberOfElements = timeDifferenceList.size(); - long timeDifferenceElement; - long timeDifferenceSum = 0; - - for (Iterator i2 = timeDifferenceList.iterator(); i2.hasNext(); ) { - timeDifferenceElement = ((Long) i2.next()).longValue(); - timeDifferenceSum += timeDifferenceElement; - } - - // Total elapsed time - String totalElapsedTime = buildTimeDifference(totalStartCalendar, totalEndCalendar); - - // Time average presentation format - pPrintStream.println("Average time difference: " + timeDifferenceSum / numberOfElements + "ms (" + numberOfElements - + " elements, total elapsed time: " + totalElapsedTime + ")"); - } - - /** - * Prints out the average time difference from a collection of {@code com.twelvemonkeys.util.DebugUtil.TimeDifference} objects to {@code System.out}. - *

- * - * @param pTimeDifferences - */ - public static void printTimeAverage(final Collection pTimeDifferences) { - printTimeAverage(pTimeDifferences, System.out); - } - - // Reflective methods - - /** - * Prints the top-wrapped class name of a {@code java.lang.Object} to a {@code java.io.PrintStream}. - *

- * @param pObject the {@code java.lang.Object} to be printed. - * @param pPrintStream the {@code java.io.PrintStream} for flushing the results. - * @see {@code java.lang.Class} - */ - public static void printClassName(final Object pObject, final PrintStream pPrintStream) { - - if (pPrintStream == null) { - System.err.println(PRINTSTREAM_IS_NULL_ERROR_MESSAGE); - return; - } - pPrintStream.println(getClassName(pObject)); - } - - /** - * Prints the top-wrapped class name of a {@code java.lang.Object} to {@code System.out}. - *

- * @param pObject the {@code java.lang.Object} to be printed. - * @see {@code java.lang.Class} - */ - public static void printClassName(final Object pObject) { - printClassName(pObject, System.out); - } - - /** - * Builds the top-wrapped class name of a {@code java.lang.Object}. - *

- * @param pObject the {@code java.lang.Object} to be analysed. - * @return the object's class name. - * @see {@code java.lang.Class} - */ - public static String getClassName(final Object pObject) { - - if (pObject == null) { - return OBJECT_IS_NULL_ERROR_MESSAGE; - } - return pObject.getClass().getName(); - } - - /** - * Prints javadoc-like, the top wrapped class fields and methods of a {@code java.lang.Object} to a {@code java.io.PrintStream}. - *

- * @param pObject the {@code java.lang.Object} to be analysed. - * @param pObjectName the name of the object instance, for identification purposes. - * @param pPrintStream the {@code java.io.PrintStream} for flushing the results. - * @see {@code java.lang.Class} - * @see {@code java.lang.reflect.Modifier} - * @see {@code java.lang.reflect.Field} - * @see {@code java.lang.reflect.Constructor} - * @see {@code java.lang.reflect.Method} - */ - public static void printClassDetails(final Object pObject, final String pObjectName, final PrintStream pPrintStream) { - - if (pPrintStream == null) { - System.err.println(PRINTSTREAM_IS_NULL_ERROR_MESSAGE); - return; - } - pPrintStream.println(getClassDetails(pObject, pObjectName)); - } - - /** - * Prints javadoc-like, the top wrapped class fields and methods of a {@code java.lang.Object} to {@code System.out}. - *

- * @param pObject the {@code java.lang.Object} to be analysed. - * @param pObjectName the name of the object instance, for identification purposes. - * @see {@code java.lang.Class} - * @see {@code java.lang.reflect.Modifier} - * @see {@code java.lang.reflect.Field} - * @see {@code java.lang.reflect.Constructor} - * @see {@code java.lang.reflect.Method} - */ - public static void printClassDetails(final Object pObject, final String pObjectName) { - printClassDetails(pObject, pObjectName, System.out); - } - - /** - * Prints javadoc-like, the top wrapped class fields and methods of a {@code java.lang.Object} to {@code System.out}. - *

- * @param pObject the {@code java.lang.Object} to be analysed. - * @see {@code java.lang.Class} - * @see {@code java.lang.reflect.Modifier} - * @see {@code java.lang.reflect.Field} - * @see {@code java.lang.reflect.Constructor} - * @see {@code java.lang.reflect.Method} - */ - public static void printClassDetails(final Object pObject) { - printClassDetails(pObject, null, System.out); - } - - /** - * Prints javadoc-like, the top wrapped class fields and methods of a {@code java.lang.Object} to a {@code java.io.PrintStream}. - *

- * @param pObject the {@code java.lang.Object} to be analysed. - * @param pPrintStream the {@code java.io.PrintStream} for flushing the results. - * @see {@code java.lang.Class} - * @see {@code java.lang.reflect.Modifier} - * @see {@code java.lang.reflect.Field} - * @see {@code java.lang.reflect.Constructor} - * @see {@code java.lang.reflect.Method} - */ - public static void printClassDetails(final Object pObject, final PrintStream pPrintStream) { - printClassDetails(pObject, null, pPrintStream); - } - - /** - * Builds a javadoc-like presentation of the top wrapped class fields and methods of a {@code java.lang.Object}. - *

- * @param pObject the {@code java.lang.Object} to be analysed. - * @return a listing of the object's class details. - * @see {@code java.lang.Class} - * @see {@code java.lang.reflect.Modifier} - * @see {@code java.lang.reflect.Field} - * @see {@code java.lang.reflect.Constructor} - * @see {@code java.lang.reflect.Method} - */ - public static String getClassDetails(final Object pObject) { - return getClassDetails(pObject, null); - } - - /** - * Builds a javadoc-like presentation of the top wrapped class fields and methods of a {@code java.lang.Object}. - *

- * @param pObject the {@code java.lang.Object} to be analysed. - * @param pObjectName the name of the object instance, for identification purposes. - * @return a listing of the object's class details. - * @see {@code java.lang.Class} - * @see {@code java.lang.reflect.Modifier} - * @see {@code java.lang.reflect.Field} - * @see {@code java.lang.reflect.Constructor} - * @see {@code java.lang.reflect.Method} - */ - public static String getClassDetails(final Object pObject, final String pObjectName) { - - if (pObject == null) { - return OBJECT_IS_NULL_ERROR_MESSAGE; - } - final String endOfLine = System.getProperty("line.separator"); - final String dividerLine = "---------------------------------------------------------"; - Class c = pObject.getClass(); - StringTokenizer tokenizedString; - String str; - String className = new String(); - String superClassName = new String(); - StringBuilder buffer = new StringBuilder(); - - // Heading - buffer.append(endOfLine); - buffer.append("**** class details"); - if (!StringUtil.isEmpty(pObjectName)) { - buffer.append(" for \"" + pObjectName + "\""); - } - buffer.append(" ****"); - buffer.append(endOfLine); - - // Package - Package p = c.getPackage(); - - if (p != null) { - buffer.append(p.getName()); - } - buffer.append(endOfLine); - - // Class or Interface - if (c.isInterface()) { - buffer.append("I n t e r f a c e "); - } else { - buffer.append("C l a s s "); - } - str = c.getName(); - tokenizedString = new StringTokenizer(str, "."); - while (tokenizedString.hasMoreTokens()) { - className = tokenizedString.nextToken().trim(); - } - str = new String(); - char[] charArray = className.toCharArray(); - - for (int i = 0; i < charArray.length; i++) { - str += charArray[i] + " "; - } - buffer.append(str); - buffer.append(endOfLine); - buffer.append(endOfLine); - - // Class Hierarch - List classNameList = new Vector(); - - classNameList.add(c.getName()); - Class superclass = c.getSuperclass(); - - while (superclass != null) { - classNameList.add(superclass.getName()); - superclass = superclass.getSuperclass(); - } - Object[] classNameArray = classNameList.toArray(); - int counter = 0; - - for (int i = classNameArray.length - 1; i >= 0; i--) { - for (int j = 0; j < counter; j++) { - buffer.append(" "); - } - if (counter > 0) { - buffer.append("|"); - buffer.append(endOfLine); - } - for (int j = 0; j < counter; j++) { - buffer.append(" "); - } - if (counter > 0) { - buffer.append("+-"); - } - buffer.append((String) classNameArray[i]); - buffer.append(endOfLine); - counter++; - } - - // Divider - buffer.append(endOfLine); - buffer.append(dividerLine); - buffer.append(endOfLine); - buffer.append(endOfLine); - - // Profile - int classModifier = c.getModifiers(); - - buffer.append(Modifier.toString(classModifier) + " "); - if (c.isInterface()) { - buffer.append("Interface "); - } else { - buffer.append("Class "); - } - buffer.append(className); - buffer.append(endOfLine); - if ((classNameArray != null) && (classNameArray[classNameArray.length - 2] != null)) { - str = (String) classNameArray[classNameArray.length - 2]; - tokenizedString = new StringTokenizer(str, "."); - while (tokenizedString.hasMoreTokens()) { - superClassName = tokenizedString.nextToken().trim(); - } - buffer.append("extends " + superClassName); - buffer.append(endOfLine); - } - if (!c.isInterface()) { - Class[] interfaces = c.getInterfaces(); - - if ((interfaces != null) && (interfaces.length > 0)) { - buffer.append("implements "); - str = interfaces[0].getName(); - tokenizedString = new StringTokenizer(str, "."); - while (tokenizedString.hasMoreTokens()) { - str = tokenizedString.nextToken().trim(); - } - buffer.append(str); - for (int i = 1; i < interfaces.length; i++) { - str = interfaces[i].getName(); - tokenizedString = new StringTokenizer(str, "."); - while (tokenizedString.hasMoreTokens()) { - str = tokenizedString.nextToken().trim(); - } - buffer.append(", " + str); - } - buffer.append(endOfLine); - } - } - - // Divider - buffer.append(endOfLine); - buffer.append(dividerLine); - buffer.append(endOfLine); - buffer.append(endOfLine); - - // Fields - buffer.append("F I E L D S U M M A R Y"); - buffer.append(endOfLine); - Field[] fields = c.getFields(); - - if (fields != null) { - for (int i = 0; i < fields.length; i++) { - buffer.append(Modifier.toString(fields[i].getType().getModifiers()) + " "); - str = fields[i].getType().getName(); - tokenizedString = new StringTokenizer(str, "."); - while (tokenizedString.hasMoreTokens()) { - str = tokenizedString.nextToken().trim(); - } - buffer.append(str + " "); - buffer.append(fields[i].getName()); - buffer.append(endOfLine); - } - } - buffer.append(endOfLine); - - // Constructors - buffer.append("C O N S T R U C T O R S U M M A R Y"); - buffer.append(endOfLine); - Constructor[] constructors = c.getConstructors(); - - if (constructors != null) { - for (int i = 0; i < constructors.length; i++) { - buffer.append(className + "("); - Class[] parameterTypes = constructors[i].getParameterTypes(); - - if (parameterTypes != null) { - if (parameterTypes.length > 0) { - str = parameterTypes[0].getName(); - tokenizedString = new StringTokenizer(str, "."); - while (tokenizedString.hasMoreTokens()) { - str = tokenizedString.nextToken().trim(); - } - buffer.append(str); - for (int j = 1; j < parameterTypes.length; j++) { - str = parameterTypes[j].getName(); - tokenizedString = new StringTokenizer(str, "."); - while (tokenizedString.hasMoreTokens()) { - str = tokenizedString.nextToken().trim(); - } - buffer.append(", " + str); - } - } - } - buffer.append(")"); - buffer.append(endOfLine); - } - } - buffer.append(endOfLine); - - // Methods - buffer.append("M E T H O D S U M M A R Y"); - buffer.append(endOfLine); - Method[] methods = c.getMethods(); - - if (methods != null) { - for (int i = 0; i < methods.length; i++) { - buffer.append(Modifier.toString(methods[i].getModifiers()) + " "); - str = methods[i].getReturnType().getName(); - tokenizedString = new StringTokenizer(str, "."); - while (tokenizedString.hasMoreTokens()) { - str = tokenizedString.nextToken().trim(); - } - buffer.append(str + " "); - buffer.append(methods[i].getName() + "("); - Class[] parameterTypes = methods[i].getParameterTypes(); - - if ((parameterTypes != null) && (parameterTypes.length > 0)) { - if (parameterTypes[0] != null) { - str = parameterTypes[0].getName(); - tokenizedString = new StringTokenizer(str, "."); - while (tokenizedString.hasMoreTokens()) { - str = tokenizedString.nextToken().trim(); - } - - // array bugfix - if (str.charAt(str.length() - 1) == ';') { - str = str.substring(0, str.length() - 1) + "[]"; - } - buffer.append(str); - for (int j = 1; j < parameterTypes.length; j++) { - str = parameterTypes[j].getName(); - tokenizedString = new StringTokenizer(str, "."); - while (tokenizedString.hasMoreTokens()) { - str = tokenizedString.nextToken().trim(); - } - buffer.append(", " + str); - } - } - } - buffer.append(")"); - buffer.append(endOfLine); - } - } - buffer.append(endOfLine); - - // Ending - buffer.append("**** class details"); - if (!StringUtil.isEmpty(pObjectName)) { - buffer.append(" for \"" + pObjectName + "\""); - } - buffer.append(" end ****"); - buffer.append(endOfLine); - return buffer.toString(); - } - - /** - * Prettyprints a large number. - *

- * - * @param pBigNumber - * @return prettyprinted number with dot-separation each 10e3. - */ - public static String getLargeNumber(final long pBigNumber) { - - StringBuilder buffer = new StringBuilder(new Long(pBigNumber).toString()); - char[] number = new Long(pBigNumber).toString().toCharArray(); - int reverseIndex = 0; - - for (int i = number.length; i >= 0; i--) { - reverseIndex++; - if ((reverseIndex % 3 == 0) && (i > 1)) { - buffer = buffer.insert(i - 1, '.'); - } - } - return buffer.toString(); - } - - /** - * Prettyprints milliseconds to ?day(s) ?h ?m ?s ?ms. - *

- * - * @param pMilliseconds - * @return prettyprinted time duration. - */ - public static String getTimeInterval(final long pMilliseconds) { - - long timeIntervalMilliseconds = pMilliseconds; - long timeIntervalSeconds = 0; - long timeIntervalMinutes = 0; - long timeIntervalHours = 0; - long timeIntervalDays = 0; - boolean printMilliseconds = true; - boolean printSeconds = false; - boolean printMinutes = false; - boolean printHours = false; - boolean printDays = false; - final long MILLISECONDS_IN_SECOND = 1000; - final long MILLISECONDS_IN_MINUTE = 60 * MILLISECONDS_IN_SECOND; // 60000 - final long MILLISECONDS_IN_HOUR = 60 * MILLISECONDS_IN_MINUTE; // 3600000 - final long MILLISECONDS_IN_DAY = 24 * MILLISECONDS_IN_HOUR; // 86400000 - StringBuilder timeIntervalBuffer = new StringBuilder(); - - // Days - if (timeIntervalMilliseconds >= MILLISECONDS_IN_DAY) { - timeIntervalDays = timeIntervalMilliseconds / MILLISECONDS_IN_DAY; - timeIntervalMilliseconds = timeIntervalMilliseconds % MILLISECONDS_IN_DAY; - printDays = true; - printHours = true; - printMinutes = true; - printSeconds = true; - } - - // Hours - if (timeIntervalMilliseconds >= MILLISECONDS_IN_HOUR) { - timeIntervalHours = timeIntervalMilliseconds / MILLISECONDS_IN_HOUR; - timeIntervalMilliseconds = timeIntervalMilliseconds % MILLISECONDS_IN_HOUR; - printHours = true; - printMinutes = true; - printSeconds = true; - } - - // Minutes - if (timeIntervalMilliseconds >= MILLISECONDS_IN_MINUTE) { - timeIntervalMinutes = timeIntervalMilliseconds / MILLISECONDS_IN_MINUTE; - timeIntervalMilliseconds = timeIntervalMilliseconds % MILLISECONDS_IN_MINUTE; - printMinutes = true; - printSeconds = true; - } - - // Seconds - if (timeIntervalMilliseconds >= MILLISECONDS_IN_SECOND) { - timeIntervalSeconds = timeIntervalMilliseconds / MILLISECONDS_IN_SECOND; - timeIntervalMilliseconds = timeIntervalMilliseconds % MILLISECONDS_IN_SECOND; - printSeconds = true; - } - - // Prettyprint - if (printDays) { - timeIntervalBuffer.append(timeIntervalDays); - if (timeIntervalDays > 1) { - timeIntervalBuffer.append("days "); - } else { - timeIntervalBuffer.append("day "); - } - } - if (printHours) { - timeIntervalBuffer.append(timeIntervalHours); - timeIntervalBuffer.append("h "); - } - if (printMinutes) { - timeIntervalBuffer.append(timeIntervalMinutes); - timeIntervalBuffer.append("m "); - } - if (printSeconds) { - timeIntervalBuffer.append(timeIntervalSeconds); - timeIntervalBuffer.append("s "); - } - if (printMilliseconds) { - timeIntervalBuffer.append(timeIntervalMilliseconds); - timeIntervalBuffer.append("ms"); - } - return timeIntervalBuffer.toString(); - } -} - - -/*--- Formatted in Sun Java Convention Style on ma, des 1, '03 ---*/ - - -/*------ Formatted by Jindent 3.23 Basic 1.0 --- http://www.jindent.de ------*/ diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/FileResource.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/FileResource.java deleted file mode 100755 index 388eaf7a..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/FileResource.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.util; - -import java.io.InputStream; -import java.io.IOException; -import java.io.File; -import java.io.FileInputStream; -import java.net.MalformedURLException; -import java.net.URL; - -/** - * FileResource class description. - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/FileResource.java#1 $ - */ -final class FileResource extends AbstractResource { - - /** - * Creates a {@code FileResource}. - * - * @param pResourceId the resource id - * @param pFile the file resource - */ - public FileResource(Object pResourceId, File pFile) { - super(pResourceId, pFile); - } - - private File getFile() { - return (File) wrappedResource; - } - - public URL asURL() { - try { - return getFile().toURL(); - } - catch (MalformedURLException e) { - throw new IllegalStateException("The file \"" + getFile().getAbsolutePath() - + "\" is not parseable as an URL: " + e.getMessage()); - } - } - - public InputStream asStream() throws IOException { - return new FileInputStream(getFile()); - } - - public long lastModified() { - return getFile().lastModified(); - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/FloatKey.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/FloatKey.java deleted file mode 100755 index 2ad7d928..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/FloatKey.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.util; - -import java.io.Serializable; - -/** - * FloatKey class description. - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/FloatKey.java#1 $ - */ -public class FloatKey extends TypedMap.AbstractKey implements Serializable { - public FloatKey() { - super(); - } - - public FloatKey(String pName) { - super(pName); - } - - public boolean isCompatibleValue(Object pValue) { - return pValue instanceof Float; - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/IntegerKey.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/IntegerKey.java deleted file mode 100755 index f35658b5..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/IntegerKey.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.util; - -import java.io.Serializable; - -/** - * IntegerKey class description. - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/IntegerKey.java#1 $ - */ -public class IntegerKey extends TypedMap.AbstractKey implements Serializable { - public IntegerKey(String pName) { - super(pName); - } - - public IntegerKey() { - } - - public boolean isCompatibleValue(Object pValue) { - return pValue instanceof Integer; - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/MappedBeanFactory.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/MappedBeanFactory.java deleted file mode 100755 index 49acf390..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/MappedBeanFactory.java +++ /dev/null @@ -1,456 +0,0 @@ -/* - * Copyright (c) 2009, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.util; - -import java.beans.BeanInfo; -import java.beans.IntrospectionException; -import java.beans.Introspector; -import java.beans.PropertyDescriptor; -import java.io.ObjectStreamException; -import java.io.Serializable; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.util.Arrays; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; - -/** - * MappedBeanFactory - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-sandbox/src/main/java/com/twelvemonkeys/sandbox/MappedBeanFactory.java#1 $ - */ -public final class MappedBeanFactory { - - // TODO: Map getMap(Object pProxy) - - // TODO: Consider a @NotNull annotation that will allow for throwing IllegalArgumentExceptions - // - Or a more general validator approach for custom fields... - - // NOTE: Specifying default values does not make much sense, as it would be possible to just add values to the map - // in the first place - - // TODO: Replace Converter varargs with new class a PropertyConverterConfiguration - // - setPropertyConverter(String propertyName, Converter from, Converter to) - // - setDefaultConverter(Class from, Class to, Converter) - // TODO: Validators? Allows for more than just NotNull checking - // TODO: Mixin support for other methods, and we are on the way to full-blown AOP.. ;-) - // TODO: Delegate for behaviour? - - // TODO: Consider being fail-fast for primitives without default values? - // Or have default values be the same as they would have been if class members (false/0/null) - // NOTE: There's a difference between a map with a null value for a key, and no presence of that key at all - - // TODO: ProperyChange support! - - private MappedBeanFactory() { - } - - static T as(final Class pClass, final Converter... pConverters) { - // TODO: Add neccessary default initializer stuff here. - return as(pClass, new LinkedHashMap(), pConverters); - } - - @SuppressWarnings({"unchecked"}) - static T as(final Class pClass, final Map pMap, final Converter... pConverters) { - return asImpl(pClass, (Map) pMap, pConverters); - } - - static T asImpl(final Class pClass, final Map pMap, final Converter[] pConverters) { - // TODO: Report clashing? Named converters? - final Map converters = new HashMap() { - @Override - public Converter get(Object key) { - Converter converter = super.get(key); - return converter != null ? converter : Converter.NULL; - } - }; - - for (Converter converter : pConverters) { - converters.put(new ConverterKey(converter.getFromType(), converter.getToType()), converter); - } - - return pClass.cast( - Proxy.newProxyInstance( - pClass.getClassLoader(), - new Class[]{pClass, Serializable.class}, // TODO: Maybe Serializable should be specified by pClass? - new MappedBeanInvocationHandler(pClass, pMap, converters) - ) - ); - } - - private static class ConverterKey { - private Class to; - private Class from; - - ConverterKey(Class pFrom, Class pTo) { - to = pTo; - from = pFrom; - } - - @Override - public boolean equals(Object pOther) { - if (this == pOther) { - return true; - } - if (pOther == null || getClass() != pOther.getClass()) { - return false; - } - - ConverterKey that = (ConverterKey) pOther; - - return from == that.from && to == that.to; - } - - @Override - public int hashCode() { - int result = to != null ? to.hashCode() : 0; - result = 31 * result + (from != null ? from.hashCode() : 0); - return result; - } - - @Override - public String toString() { - return String.format("%s->%s", from, to); - } - } - - public static interface Converter { - - Converter NULL = new Converter() { - public Class getFromType() { - return null; - } - - public Class getToType() { - return null; - } - - public Object convert(Object value, Object old) { - if (value == null) { - return value; - } - throw new ClassCastException(value.getClass().getName()); - } - }; - - Class getFromType(); - - Class getToType(); - - T convert(F value, T old); - } - - // Add guards for null values by throwing IllegalArgumentExceptions for parameters - // TODO: Throw IllegalArgumentException at CREATION time, if value in map is null for a method with @NotNull return type - @Retention(RetentionPolicy.RUNTIME) - @Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD}) - static @interface NotNull { - } - - // For setter methods to have automatic property change support - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.METHOD) - // TODO: Consider field as well? - static @interface Observable { - } - - // TODO: Decide on default value annotation - // Alternate default value annotation - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.METHOD) - static @interface DefaultValue { - boolean booleanValue() default false; - byte byteValue() default 0; - char charValue() default 0; - short shortValue() default 0; - int intValue() default 0; - float floatValue() default 0f; - long longValue() default 0l; - double doubleValue() default 0d; - } - - - // Default values for primitive types - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.METHOD) - static @interface DefaultBooleanValue { - boolean value() default false; - } - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.METHOD) - static @interface DefaultByteValue { - byte value() default 0; - } - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.METHOD) - static @interface DefaultCharValue { - char value() default 0; - } - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.METHOD) - static @interface DefaultShortValue { - short value() default 0; - } - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.METHOD) - static @interface DefaultIntValue { - int value() default 0; - } - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.METHOD) - static @interface DefaultFloatValue { - float value() default 0; - } - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.METHOD) - static @interface DefaultLongValue { - long value() default 0; - } - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.METHOD) - static @interface DefaultDouleValue { - double value() default 0; - } - - // TODO: Does it make sense to NOT just put the value in the map? - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.METHOD) - private static @interface DefaultStringValue { - String value(); // TODO: Do we want a default empty string? - } - - private static class MappedBeanInvocationHandler implements InvocationHandler, Serializable { - - private static final Method OBJECT_TO_STRING = getObjectMethod("toString"); - private static final Method OBJECT_HASH_CODE = getObjectMethod("hashCode"); - private static final Method OBJECT_EQUALS = getObjectMethod("equals", Object.class); - private static final Method OBJECT_CLONE = getObjectMethod("clone"); - - private final Class mClass; - private final Map mMap; - private final Map mConverters; - - private transient Map mReadMethods = new HashMap(); - private transient Map mWriteMethods = new HashMap(); - - private static Method getObjectMethod(final String pMethodName, final Class... pParams) { - try { - return Object.class.getDeclaredMethod(pMethodName, pParams); - } - catch (NoSuchMethodException e) { - throw new Error(e.getMessage(), e); - } - } - - private Object readResolve() throws ObjectStreamException { - mReadMethods = new HashMap(); - mWriteMethods = new HashMap(); - - introspectBean(mClass, mReadMethods, mWriteMethods); - - return this; - } - - public MappedBeanInvocationHandler(Class pClass, Map pMap, Map pConverters) { - mClass = pClass; - mMap = pMap; - mConverters = pConverters; - - introspectBean(mClass, mReadMethods, mWriteMethods); - } - - private void introspectBean(Class pClass, Map pReadMethods, Map pWriteMethods) { - try { - BeanInfo info = Introspector.getBeanInfo(pClass); - PropertyDescriptor[] descriptors = info.getPropertyDescriptors(); - for (PropertyDescriptor descriptor : descriptors) { - String name = descriptor.getName(); - - Method read = descriptor.getReadMethod(); - if (read != null) { - pReadMethods.put(read, name); - } - - Method write = descriptor.getWriteMethod(); - if (write != null) { - pWriteMethods.put(write, name); - } - } - } - catch (IntrospectionException e) { - throw new IllegalArgumentException(String.format("Class %s not introspectable: %s", pClass, e.getMessage()) , e); - } - } - - public Object invoke(final Object pProxy, final Method pMethod, final Object[] pArguments) throws Throwable { - String property = mReadMethods.get(pMethod); - if (property != null) { - if (pArguments == null || pArguments.length == 0) { - Object value = mMap.get(property); - Class type = pMethod.getReturnType(); - - if (!isCompatible(value, type)) { - return mConverters.get(new ConverterKey(value != null ? value.getClass() : Void.class, unBoxType(type))).convert(value, null); - } - return value; - } - else { - throw new IllegalArgumentException("Unknown parameters for " + pMethod + ": " + Arrays.toString(pArguments)); - } - } - - property = mWriteMethods.get(pMethod); - if (property != null) { - if (pArguments.length == 1) { - Object value = pArguments[0]; - - // Make sure we don't accidentally overwrite a value that looks like ours... - Object oldValue = mMap.get(property); - Class type = pMethod.getParameterTypes()[0]; - if (oldValue != null && !isCompatible(oldValue, type)) { - value = mConverters.get(new ConverterKey(type, oldValue.getClass())).convert(value, oldValue); - } - return mMap.put(property, value); - } - else { - throw new IllegalArgumentException("Unknown parameters for " + pMethod + ": " + Arrays.toString(pArguments)); - } - } - - if (pMethod.equals(OBJECT_TO_STRING)) { - return proxyToString(); - } - if (pMethod.equals(OBJECT_EQUALS)) { - return proxyEquals(pProxy, pArguments[0]); - } - if (pMethod.equals(OBJECT_HASH_CODE)) { - return proxyHashCode(); - } - if (pMethod.getName().equals(OBJECT_CLONE.getName()) - && Arrays.equals(pMethod.getParameterTypes(), OBJECT_CLONE.getParameterTypes()) - && OBJECT_CLONE.getReturnType().isAssignableFrom(pMethod.getReturnType())) { - return proxyClone(); - } - - // Other methods not handled (for now) - throw new AbstractMethodError(pMethod.getName()); - } - - private boolean isCompatible(final Object pValue, final Class pType) { - return pValue == null && !pType.isPrimitive() || unBoxType(pType).isInstance(pValue); - } - - private Class unBoxType(final Class pType) { - if (pType.isPrimitive()) { - if (pType == boolean.class) { - return Boolean.class; - } - if (pType == byte.class) { - return Byte.class; - } - if (pType == char.class) { - return Character.class; - } - if (pType == short.class) { - return Short.class; - } - if (pType == int.class) { - return Integer.class; - } - if (pType == float.class) { - return Float.class; - } - if (pType == long.class) { - return Long.class; - } - if (pType == double.class) { - return Double.class; - } - - throw new IllegalArgumentException("Unknown type: " + pType); - } - return pType; - } - - private int proxyHashCode() { - // NOTE: Implies mMap instance must follow Map.equals contract - return mMap.hashCode(); - } - - private boolean proxyEquals(final Object pThisProxy, final Object pThat) { - if (pThisProxy == pThat) { - return true; - } - if (pThat == null) { - return false; - } - - // TODO: Document that subclasses are considered equal (if no extra properties) - if (!mClass.isInstance(pThat)) { - return false; - } - if (!Proxy.isProxyClass(pThat.getClass())) { - return false; - } - - // NOTE: This implies that we should put default values in map at creation time - // NOTE: Implies mMap instance must follow Map.equals contract - InvocationHandler handler = Proxy.getInvocationHandler(pThat); - return handler.getClass() == getClass() && mMap.equals(((MappedBeanInvocationHandler) handler).mMap); - - } - - private Object proxyClone() throws CloneNotSupportedException { - return as( - mClass, - new LinkedHashMap(mMap), - mConverters.values().toArray(new Converter[mConverters.values().size()]) - ); - } - - private String proxyToString() { - return String.format("%s$MapProxy@%s: %s", mClass.getName(), System.identityHashCode(this), mMap); - } - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/PaintKey.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/PaintKey.java deleted file mode 100755 index 1005b053..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/PaintKey.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.util; - -import java.awt.*; -import java.io.Serializable; - -/** - * PaintKey class description. - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/PaintKey.java#1 $ - */ -public class PaintKey extends TypedMap.AbstractKey implements Serializable { - public PaintKey() { - super(); - } - - public PaintKey(String pName) { - super(pName); - } - - public boolean isCompatibleValue(Object pValue) { - return pValue instanceof Paint; - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/PersistentMap.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/PersistentMap.java deleted file mode 100755 index e87673b7..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/PersistentMap.java +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Copyright (c) 2009, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.util; - -import com.twelvemonkeys.io.FileUtil; - -import java.io.*; -import java.util.*; - -import static com.twelvemonkeys.lang.Validate.notNull; - -/** - * PersistentMap - * - * @author Harald Kuhr - * @author last modified by $Author: haraldk$ - * @version $Id: PersistentMap.java,v 1.0 May 13, 2009 2:31:29 PM haraldk Exp$ - */ -public class PersistentMap extends AbstractMap{ - public static final FileFilter DIRECTORIES = new FileFilter() { - public boolean accept(File file) { - return file.isDirectory(); - } - - @Override - public String toString() { - return "[All folders]"; - } - }; - private static final String INDEX = ".index"; - - private final File root; - private final Map index = new LinkedHashMap(); - - private boolean mutable = true; - - - // Idea 2.0: - // - Create directory per hashCode - // - Create file per object in that directory - // - Name file after serialized form of key? Base64? - // - Special case for String/Integer/Long etc? - // - Or create index file in directory with serialized objects + name (uuid) of file - - // TODO: Consider single index file? Or a few? In root directory instead of each directory - // Consider a RAF/FileChannel approach instead of streams - how do we discard portions of a RAF? - // - Need to keep track of used/unused parts of file, scan for gaps etc...? - // - Need to periodically truncate and re-build the index (always as startup, then at every N puts/removes?) - - /*public */PersistentMap(String id) { - this(new File(FileUtil.getTempDirFile(), id)); - } - - public PersistentMap(File root) { - this.root = notNull(root); - - init(); - } - - private void init() { - if (!root.exists() && !root.mkdirs()) { - throw new IllegalStateException(String.format("'%s' does not exist/could not be created", root.getAbsolutePath())); - } - else if (!root.isDirectory()) { - throw new IllegalStateException(String.format("'%s' exists but is not a directory", root.getAbsolutePath())); - } - - if (!root.canRead()) { - throw new IllegalStateException(String.format("'%s' is not readable", root.getAbsolutePath())); - } - - if (!root.canWrite()) { - mutable = false; - } - - FileUtil.visitFiles(root, DIRECTORIES, new Visitor() { - public void visit(File dir) { - // - Read .index file - // - Add entries to index - ObjectInputStream input = null; - try { - input = new ObjectInputStream(new FileInputStream(new File(dir, INDEX))); - while (true) { - @SuppressWarnings({"unchecked"}) - K key = (K) input.readObject(); - String fileName = (String) input.readObject(); - index.put(key, UUID.fromString(fileName)); - } - } - catch (EOFException eof) { - // break here - } - catch (IOException e) { - throw new RuntimeException(e); - } - catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } - finally { - FileUtil.close(input); - } - } - }); - } - - @Override - public Set> entrySet() { - return new AbstractSet>() { - @Override - public Iterator> iterator() { - return new Iterator>() { - Iterator> indexIter = index.entrySet().iterator(); - - public boolean hasNext() { - return indexIter.hasNext(); - } - - public Entry next() { - return new Entry() { - final Entry entry = indexIter.next(); - - public K getKey() { - return entry.getKey(); - } - - public V getValue() { - K key = entry.getKey(); - int hash = key != null ? key.hashCode() : 0; - return readVal(hash, entry.getValue()); - } - - public V setValue(V value) { - K key = entry.getKey(); - int hash = key != null ? key.hashCode() : 0; - return writeVal(key, hash, entry.getValue(), value, getValue()); - } - }; - } - - public void remove() { - indexIter.remove(); - } - }; - } - - @Override - public int size() { - return index.size(); - } - }; - } - - @Override - public int size() { - return index.size(); - } - - @Override - public V put(K key, V value) { - V oldVal = null; - - UUID uuid = index.get(key); - int hash = key != null ? key.hashCode() : 0; - - if (uuid != null) { - oldVal = readVal(hash, uuid); - } - - return writeVal(key, hash, uuid, value, oldVal); - } - - private V writeVal(K key, int hash, UUID uuid, V value, V oldVal) { - if (!mutable) { - throw new UnsupportedOperationException(); - } - - File bucket = new File(root, hashToFileName(hash)); - if (!bucket.exists() && !bucket.mkdirs()) { - throw new IllegalStateException(String.format("Could not create bucket '%s'", bucket)); - } - - if (uuid == null) { - // No uuid means new entry - uuid = UUID.randomUUID(); - - File idx = new File(bucket, INDEX); - - ObjectOutputStream output = null; - try { - output = new ObjectOutputStream(new FileOutputStream(idx, true)); - output.writeObject(key); - output.writeObject(uuid.toString()); - - index.put(key, uuid); - } - catch (IOException e) { - throw new RuntimeException(e); - } - finally { - FileUtil.close(output); - } - } - - File entry = new File(bucket, uuid.toString()); - if (value != null) { - ObjectOutputStream output = null; - try { - output = new ObjectOutputStream(new FileOutputStream(entry)); - output.writeObject(value); - - } - catch (IOException e) { - throw new RuntimeException(e); - } - finally { - FileUtil.close(output); - } - } - else if (entry.exists()) { - if (!entry.delete()) { - throw new IllegalStateException(String.format("'%s' could not be deleted", entry)); - } - } - - return oldVal; - } - - private String hashToFileName(int hash) { - return Integer.toString(hash, 16); - } - - @Override - public V get(Object key) { - UUID uuid = index.get(key); - - if (uuid != null) { - int hash = key != null ? key.hashCode() : 0; - return readVal(hash, uuid); - } - - return null; - } - - private V readVal(final int hash, final UUID uuid) { - File bucket = new File(root, hashToFileName(hash)); - File entry = new File(bucket, uuid.toString()); - - if (entry.exists()) { - ObjectInputStream input = null; - try { - input = new ObjectInputStream(new FileInputStream(entry)); - //noinspection unchecked - return (V) input.readObject(); - } - catch (IOException e) { - throw new RuntimeException(e); - } - catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } - finally { - FileUtil.close(input); - } - } - - return null; - } - - @Override - public V remove(Object key) { - // TODO!!! - return super.remove(key); - } - - // TODO: Should override size, put, get, remove, containsKey and containsValue - - - -} - - - -/* -Memory mapped file? -Delta sync? - -Persistent format - -Header - File ID 4-8 bytes - Size (entries) - - PersistentEntry pointer array block (PersistentEntry 0) - Size (bytes) - Next entry pointer block address (0 if last) - PersistentEntry 1 address/offset + key - ... - PersistentEntry n address/offset + key - - PersistentEntry 1 - Size (bytes)? - Serialized value or pointer array block - ... - PersistentEntry n - Size (bytes)? - Serialized value or pointer array block - -*/ \ No newline at end of file diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/Rectangle2DKey.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/Rectangle2DKey.java deleted file mode 100755 index ee4d0b7f..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/Rectangle2DKey.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.util; - -import java.awt.geom.Rectangle2D; -import java.io.Serializable; - -/** - * Rectangle2DKey class description. - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/Rectangle2DKey.java#1 $ - */ -public class Rectangle2DKey extends TypedMap.AbstractKey implements Serializable { - public Rectangle2DKey() { - super(); - } - - public Rectangle2DKey(String pName) { - super(pName); - } - - public boolean isCompatibleValue(Object pValue) { - return pValue instanceof Rectangle2D; - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/Resource.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/Resource.java deleted file mode 100755 index 18f04563..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/Resource.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.util; - -import java.io.InputStream; -import java.io.IOException; -import java.net.URL; - -/** - * Resource class description. - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/Resource.java#1 $ - */ -public interface Resource { - /** - * Returns the id of this resource. - * - * The id might be a {@code URL}, a {@code File} or a string - * representation of some system resource. - * It will always be equal to the {@code resourceId} parameter - * sent to the {@link ResourceMonitor#addResourceChangeListener} method - * for a given resource. - * - * @return the id of this resource - */ - public Object getId(); - - /** - * Returns the {@code URL} for the resource. - * - * @return the URL for the resource - */ - public URL asURL(); - - /** - * Opens an input stream, that reads from this resource. - * - * @return an input stream, that reads from this resource. - * - * @throws IOException if an I/O exception occurs - */ - public InputStream asStream() throws IOException; - - /** - * Returns the last modified time. - * Should only be used for comparison. - * - * @return the time of the last modification of this resource, or - * {@code -1} if the last modification time cannot be determined. - */ - public long lastModified(); -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/ResourceChangeListener.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/ResourceChangeListener.java deleted file mode 100755 index 17208c81..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/ResourceChangeListener.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.util; - -import java.util.EventListener; - -/** - * An {@code EventListener} that listens for updates in file or system - * resources. - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/ResourceChangeListener.java#1 $ - */ -public interface ResourceChangeListener extends EventListener { - /** - * Invoked when a resource is changed. - * Implementations that listens for multiple events, should check that - * {@code Resource.getId()} is equal to the {@code resourceId} parameter - * sent to the {@link ResourceMonitor#addResourceChangeListener} method. - * - * @param pResource changed file/url/etc. - */ - void resourceChanged(Resource pResource); -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/ResourceMonitor.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/ResourceMonitor.java deleted file mode 100755 index c594de70..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/ResourceMonitor.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.util; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.net.URL; -import java.util.Timer; -import java.util.TimerTask; -import java.util.Map; -import java.util.HashMap; - -// TODO: Could this be used for change-aware classloader? Woo.. -/** - * Monitors changes is files and system resources. - * - * Based on example code and ideas from - * Java - * Tip 125: Set your timer for dynamic properties. - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/ResourceMonitor.java#1 $ - */ -public abstract class ResourceMonitor { - - private static final ResourceMonitor INSTANCE = new ResourceMonitor() {}; - - private Timer timer; - - private final Map timerEntries; - - public static ResourceMonitor getInstance() { - return INSTANCE; - } - - /** - * Creates a {@code ResourceMonitor}. - */ - protected ResourceMonitor() { - // Create timer, run timer thread as daemon... - timer = new Timer(true); - timerEntries = new HashMap(); - } - - /** - * Add a monitored {@code Resource} with a {@code ResourceChangeListener}. - * - * The {@code reourceId} might be a {@code File} a {@code URL} or a - * {@code String} containing a file path, or a path to a resource in the - * class path. Note that class path resources are resolved using the - * given {@code ResourceChangeListener}'s {@code ClassLoader}, then - * the current {@code Thread}'s context class loader, if not found. - * - * @param pListener pListener to notify when the file changed. - * @param pResourceId id of the resource to monitor (a {@code File} - * a {@code URL} or a {@code String} containing a file path). - * @param pPeriod polling pPeriod in milliseconds. - * - * @see ClassLoader#getResource(String) - */ - public void addResourceChangeListener(ResourceChangeListener pListener, - Object pResourceId, long pPeriod) throws IOException { - // Create the task - ResourceMonitorTask task = new ResourceMonitorTask(pListener, pResourceId); - - // Get unique Id - Object resourceId = getResourceId(pResourceId, pListener); - - // Remove the old task for this Id, if any, and register the new one - synchronized (timerEntries) { - removeListenerInternal(resourceId); - timerEntries.put(resourceId, task); - } - - timer.schedule(task, pPeriod, pPeriod); - } - - /** - * Remove the {@code ResourceChangeListener} from the notification list. - * - * @param pListener the pListener to be removed. - * @param pResourceId name of the resource to monitor. - */ - public void removeResourceChangeListener(ResourceChangeListener pListener, Object pResourceId) { - synchronized (timerEntries) { - removeListenerInternal(getResourceId(pResourceId, pListener)); - } - } - - private void removeListenerInternal(Object pResourceId) { - ResourceMonitorTask task = timerEntries.remove(pResourceId); - - if (task != null) { - task.cancel(); - } - } - - private Object getResourceId(Object pResourceName, ResourceChangeListener pListener) { - return pResourceName.toString() + System.identityHashCode(pListener); - } - - private void fireResourceChangeEvent(ResourceChangeListener pListener, Resource pResource) { - pListener.resourceChanged(pResource); - } - - /** - * - */ - private class ResourceMonitorTask extends TimerTask { - ResourceChangeListener listener; - Resource monitoredResource; - long lastModified; - - public ResourceMonitorTask(ResourceChangeListener pListener, Object pResourceId) throws IOException { - listener = pListener; - lastModified = 0; - - String resourceId = null; - File file = null; - URL url = null; - if (pResourceId instanceof File) { - file = (File) pResourceId; - resourceId = file.getAbsolutePath(); // For use by exception only - } - else if (pResourceId instanceof URL) { - url = (URL) pResourceId; - if ("file".equals(url.getProtocol())) { - file = new File(url.getFile()); - } - resourceId = url.toExternalForm(); // For use by exception only - } - else if (pResourceId instanceof String) { - resourceId = (String) pResourceId; // This one might be looked up - file = new File(resourceId); - } - - if (file != null && file.exists()) { - // Easy, this is a file - monitoredResource = new FileResource(pResourceId, file); - //System.out.println("File: " + monitoredResource); - } - else { - // No file there, but is it on CLASSPATH? - if (url == null) { - url = pListener.getClass().getClassLoader().getResource(resourceId); - } - if (url == null) { - url = Thread.currentThread().getContextClassLoader().getResource(resourceId); - } - - if (url != null && "file".equals(url.getProtocol()) - && (file = new File(url.getFile())).exists()) { - // It's a file in classpath, so try this as an optimization - monitoredResource = new FileResource(pResourceId, file); - //System.out.println("File: " + monitoredResource); - } - else if (url != null) { - // No, not a file, might even be an external resource - monitoredResource = new URLResource(pResourceId, url); - //System.out.println("URL: " + monitoredResource); - } - else { - throw new FileNotFoundException(resourceId); - } - } - - lastModified = monitoredResource.lastModified(); - } - - public void run() { - long lastModified = monitoredResource.lastModified(); - - if (lastModified != this.lastModified) { - this.lastModified = lastModified; - fireResourceChangeEvent(listener, monitoredResource); - } - } - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/StringKey.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/StringKey.java deleted file mode 100755 index 67b5228e..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/StringKey.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.util; - -import java.io.Serializable; - -/** - * StringKey class description. - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/StringKey.java#1 $ - */ -public class StringKey extends TypedMap.AbstractKey implements Serializable { - public StringKey() { - super(); - } - - public StringKey(String pName) { - super(pName); - } - - public boolean isCompatibleValue(Object pValue) { - return pValue instanceof String; - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/TypedMap.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/TypedMap.java deleted file mode 100755 index 995e12d6..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/TypedMap.java +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.util; - -import java.util.Map; -import java.util.HashMap; -import java.util.Collection; -import java.util.Set; -import java.io.Serializable; - -/** - * This {@code Map} implementation guarantees that the values have a type that - * are compatible with it's key. Different keys may have different types. - * - * @see TypedMap.Key - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/TypedMap.java#1 $ - */ -public class TypedMap implements Map, Serializable { - - /** - * The wrapped map - */ - protected Map entries; - - /** - * Creates a {@code TypedMap}. - * This {@code TypedMap} will be backed by a new {@code HashMap} instance. - */ - public TypedMap() { - entries = new HashMap(); - } - - /** - * Creates a {@code TypedMap} containing the same elements as the given - * map. - * This {@code TypedMap} will be backed by a new {@code HashMap} instance, - * and not the map passed in as a paramter. - *

- * This is constructor is here to comply with the reccomendations for - * "standard" constructors in the {@code Map} interface. - * - * @param pMap the map used to populate this map - * @throws ClassCastException if all keys in the map are not instances of - * {@code TypedMap.Key}. - * @see java.util.Map - * @see #TypedMap(java.util.Map, boolean) - */ - public TypedMap(Map pMap) { - this(); - - if (pMap != null) { - putAll(pMap); - } - } - - /** - * Creates a {@code TypedMap}. - * This {@code TypedMap} will be backed by the given {@code Map}. - *

- * Note that structurally modifying the backing map directly (not through - * this map or its collection views), is not allowed, and will produce - * undeterministic exceptions. - * - * @param pBacking the map that will be used as backing. - * @param pUseElements if {@code true}, the elements in the map are - * retained. Otherwise, the map is cleared. For an empty {@code Map} the - * parameter has no effect. - * @throws ClassCastException if {@code pUseElements} is {@code true} - * all keys in the map are not instances of {@code TypedMap.Key}. - */ - public TypedMap(Map pBacking, boolean pUseElements) { - if (pBacking == null) { - throw new IllegalArgumentException("backing == null"); - } - - // This is safe, as we re-insert all values later - //noinspection unchecked - entries = (Map) pBacking; - - // Re-insert all elements to avoid undeterministic ClassCastExceptions - if (pUseElements) { - putAll(pBacking); - } - else if (entries.size() > 0) { - entries.clear(); - } - } - - /** - * Returns the number of key-value mappings in this map. If the - * map contains more than {@code Integer.MAX_VALUE} elements, returns - * {@code Integer.MAX_VALUE}. - * - * @return the number of key-value mappings in this map. - */ - public int size() { - return entries.size(); - } - - /** - * Returns {@code true} if this map contains no key-value mappings. - * - * @return {@code true} if this map contains no key-value mappings. - */ - public boolean isEmpty() { - return entries.isEmpty(); - } - - /** - * Returns {@code true} if this map contains a mapping for the specified - * key. - * - * @param pKey key whose presence in this map is to be tested. - * @return {@code true} if this map contains a mapping for the specified - * key. - */ - public boolean containsKey(Object pKey) { - return entries.containsKey(pKey); - } - - /** - * Returns {@code true} if this map maps one or more keys to the - * specified value. More formally, returns {@code true} if and only if - * this map contains at least one mapping to a value {@code v} such that - * {@code (pValue==null ? v==null : pValue.equals(v))}. This operation - * will probably require time linear in the map size for most - * implementations of the {@code Map} interface. - * - * @param pValue value whose presence in this map is to be tested. - * @return {@code true} if this map maps one or more keys to the - * specified value. - */ - public boolean containsValue(Object pValue) { - return entries.containsValue(pValue); - } - - /** - * Returns the value to which this map maps the specified key. Returns - * {@code null} if the map contains no mapping for this key. A return - * value of {@code null} does not necessarily indicate that the - * map contains no mapping for the key; it's also possible that the map - * explicitly maps the key to {@code null}. The {@code containsKey} - * operation may be used to distinguish these two cases. - * - * @param pKey key whose associated value is to be returned. - * @return the value to which this map maps the specified key, or - * {@code null} if the map contains no mapping for this key. - * @see #containsKey(java.lang.Object) - */ - public V get(Object pKey) { - return entries.get(pKey); - } - - /** - * Associates the specified value with the specified key in this map. - * If the map previously contained a mapping for - * the key, the old value is replaced. - * - * @param pKey key with which the specified value is to be associated. - * @param pValue value to be associated with the specified key. - * - * @return previous value associated with specified key, or {@code null} - * if there was no mapping for key. A {@code null} return can - * also indicate that the map previously associated {@code null} - * with the specified pKey, if the implementation supports - * {@code null} values. - * - * @throws IllegalArgumentException if the value is not compatible with the - * key. - * - * @see TypedMap.Key - */ - public V put(K pKey, V pValue) { - if (!pKey.isCompatibleValue(pValue)) { - throw new IllegalArgumentException("incompatible value for key"); - } - return entries.put(pKey, pValue); - } - - /** - * Removes the mapping for this key from this map if present (optional - * operation). - * - * @param pKey key whose mapping is to be removed from the map. - * @return previous value associated with specified key, or {@code null} - * if there was no mapping for key. A {@code null} return can - * also indicate that the map previously associated {@code null} - * with the specified key, if the implementation supports - * {@code null} values. - */ - public V remove(Object pKey) { - return entries.remove(pKey); - } - - /** - * Copies all of the mappings from the specified map to this map - * (optional operation). These mappings will replace any mappings that - * this map had for any of the keys currently in the specified map. - *

- * Note: If you override this method, make sure you add each element through - * the put method, to avoid resource leaks and undeterministic class casts. - * - * @param pMap Mappings to be stored in this map. - */ - public void putAll(Map pMap) { - for (final Entry e : pMap.entrySet()) { - put(e.getKey(), e.getValue()); - } - } - - /** - * Removes all mappings from this map (optional operation). - */ - public void clear() { - entries.clear(); - } - - public Collection values() { - return entries.values(); - } - - public Set> entrySet() { - return entries.entrySet(); - } - - public Set keySet() { - return entries.keySet(); - } - - /** - * Keys for use with {@code TypedMap} must implement this interface. - * - * @see #isCompatibleValue(Object) - */ - public static interface Key { - - /** - * Tests if the given value is compatible with this {@code Key}. - * Only compatible values may be passed to the - * {@code TypedMap.put} method. - * - * @param pValue the value to test for compatibility - * @return {@code true} if compatible, otherwise {@code false} - */ - boolean isCompatibleValue(Object pValue); - } - - /** - * An abstract {@code Key} implementation that allows keys to have - * meaningful names. - */ - public static abstract class AbstractKey implements Key, Serializable { - private final String mStringRep; - - /** - * Creates a {@code Key} with the given name. - * - * @param pName name of this key - */ - public AbstractKey(String pName) { - if (pName == null) { - throw new IllegalArgumentException("name == null"); - } - mStringRep = getClass().getName() + '[' + pName + ']'; - } - - /** - * Creates a {@code Key} with no name. - */ - public AbstractKey() { - this("null"); - } - - @Override - public String toString() { - return mStringRep; - } - - @Override - public boolean equals(Object obj) { - return obj == this || - (obj != null && obj.getClass() == getClass() && - mStringRep.equals(((AbstractKey) obj).mStringRep)); - } - - @Override - public int hashCode() { - return mStringRep.hashCode(); - } - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/URLResource.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/URLResource.java deleted file mode 100755 index 3e0cb63a..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/URLResource.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.util; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.net.URLConnection; - -/** - * URLResource class description. - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/URLResource.java#1 $ - */ -final class URLResource extends AbstractResource { - - // NOTE: For the time being, we rely on the URL class (and helpers) to do - // some smart caching and reuse of connections... - // TODO: Change the implementation if this is a problem - private long lastModified = -1; - - /** - * Creates a {@code URLResource}. - * - * @param pResourceId the resource id - * @param pURL the URL resource - */ - public URLResource(Object pResourceId, URL pURL) { - super(pResourceId, pURL); - } - - private URL getURL() { - return (URL) wrappedResource; - } - - public URL asURL() { - return getURL(); - } - - public InputStream asStream() throws IOException { - URLConnection connection = getURL().openConnection(); - connection.setAllowUserInteraction(false); - connection.setUseCaches(true); - return connection.getInputStream(); - } - - public long lastModified() { - try { - URLConnection connection = getURL().openConnection(); - connection.setAllowUserInteraction(false); - connection.setUseCaches(true); - connection.setIfModifiedSince(lastModified); - - lastModified = connection.getLastModified(); - } - catch (IOException ignore) { - } - - return lastModified; - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/UUIDFactory.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/UUIDFactory.java deleted file mode 100644 index 2b3208fd..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/UUIDFactory.java +++ /dev/null @@ -1,410 +0,0 @@ -/* - * Copyright (c) 2012, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.util; - -import com.twelvemonkeys.lang.StringUtil; - -import java.net.NetworkInterface; -import java.net.SocketException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.util.*; - -/** - * A factory for creating {@code UUID}s not directly supported by {@link java.util.UUID java.util.UUID}. - *

- * This class can create version 1 time based {@code UUID}s, using either IEEE 802 (mac) address or random "node" value - * as well as version 5 SHA1 hash based {@code UUID}s. - *

- *

- * The timestamp value for version 1 {@code UUID}s will use a high precision clock, when available to the Java VM. - * If the Java system clock does not offer the needed precision, the timestamps will fall back to 100-nanosecond - * increments, to avoid duplicates. - *

- *

- * - * The node value for version 1 {@code UUID}s will, by default, reflect the IEEE 802 (mac) address of one of - * the network interfaces of the local computer. This node value can be manually overridden by setting - * the system property {@code "com.twelvemonkeys.util.UUID.node"} to a valid IEEE 802 address, on the form - * {@code "12:34:56:78:9a:bc"} or {@code "12-34-45-78-9a-bc"}. - *

- *

- * - * The node value for the random "node" based version 1 {@code UUID}s will be stable for the lifetime of the VM. - *

- * - * @author Harald Kuhr - * @author last modified by $Author: haraldk$ - * @version $Id: UUIDFactory.java,v 1.0 27.02.12 09:45 haraldk Exp$ - * - * @see RFC 4122 - * @see Wikipedia - * @see java.util.UUID - */ -public final class UUIDFactory { - private static final String NODE_PROPERTY = "com.twelvemonkeys.util.UUID.node"; - - /** - * The Nil UUID: {@code "00000000-0000-0000-0000-000000000000"}. - * - * The nil UUID is special form of UUID that is specified to have all - * 128 bits set to zero. Not particularly useful, unless as a placeholder or template. - * - * @see RFC 4122 4.1.7. Nil UUID - */ - public static final UUID NIL = new UUID(0l, 0l); - - private static final SecureRandom SECURE_RANDOM = new SecureRandom(); - - private static final Comparator COMPARATOR = new UUIDComparator(); - - // Assumes MAC address is constant, which it may not be if a network card is replaced - static final long MAC_ADDRESS_NODE = getMacAddressNode(); - - static final long SECURE_RANDOM_NODE = getSecureRandomNode(); - - private static long getSecureRandomNode() { - // Creates a completely random "node" value, with the unicast bit set to 1, as outlined in RFC 4122. - return 1l << 40 | SECURE_RANDOM.nextLong() & 0xffffffffffffl; - } - - private static long getMacAddressNode() { - long[] addressNodes; - - String nodeProperty = System.getProperty(NODE_PROPERTY); - - // Read mac address/node from system property, to allow user-specified node addresses. - if (!StringUtil.isEmpty(nodeProperty)) { - addressNodes = parseMacAddressNodes(nodeProperty); - } - else { - addressNodes = MacAddressFinder.getMacAddressNodes(); - } - - // TODO: The UUID spec allows us to use multiple nodes, when available, to create more UUIDs per time unit... - // For example in a round robin fashion? - return addressNodes != null && addressNodes.length > 0 ? addressNodes[0] : -1; - } - - static long[] parseMacAddressNodes(final String nodeProperty) { - // Parse comma-separated list mac addresses on format 00:11:22:33:44:55 / 00-11-22-33-44-55 - String[] nodesStrings = nodeProperty.trim().split(",\\W*"); - long[] addressNodes = new long[nodesStrings.length]; - - for (int i = 0, nodesStringsLength = nodesStrings.length; i < nodesStringsLength; i++) { - String nodesString = nodesStrings[i]; - - try { - String[] nodes = nodesString.split("(?<=(^|\\W)[0-9a-fA-F]{2})\\W(?=[0-9a-fA-F]{2}(\\W|$))", 6); - - long nodeAddress = 0; - - // Network byte order - nodeAddress |= (long) (Integer.parseInt(nodes[0], 16) & 0xff) << 40; - nodeAddress |= (long) (Integer.parseInt(nodes[1], 16) & 0xff) << 32; - nodeAddress |= (long) (Integer.parseInt(nodes[2], 16) & 0xff) << 24; - nodeAddress |= (long) (Integer.parseInt(nodes[3], 16) & 0xff) << 16; - nodeAddress |= (long) (Integer.parseInt(nodes[4], 16) & 0xff) << 8; - nodeAddress |= (long) (Integer.parseInt(nodes[5], 16) & 0xff); - - addressNodes[i] = nodeAddress; - } - catch (RuntimeException e) { - // May be NumberformatException from parseInt or ArrayIndexOutOfBounds from nodes array - NumberFormatException formatException = new NumberFormatException(String.format("Bad IEEE 802 node address: '%s' (from system property %s)", nodesString, NODE_PROPERTY)); - formatException.initCause(e); - throw formatException; - } - } - - return addressNodes; - } - - private UUIDFactory() {} - - /** - * Creates a type 5 (name based) {@code UUID} based on the specified byte array. - * This method is effectively identical to {@link UUID#nameUUIDFromBytes}, except that this method - * uses a SHA1 hash instead of the MD5 hash used in the type 3 {@code UUID}s. - * RFC 4122 states that "SHA-1 is preferred" over MD5, without giving a reason for why. - * - * @param name a byte array to be used to construct a {@code UUID} - * @return a {@code UUID} generated from the specified array. - * - * @see RFC 4122 4.3. Algorithm for Creating a Name-Based UUID - * @see RFC 4122 appendix A - * @see UUID#nameUUIDFromBytes(byte[]) - */ - public static UUID nameUUIDv5FromBytes(byte[] name) { - // Based on code from OpenJDK UUID#nameUUIDFromBytes + private byte[] constructor - MessageDigest md; - - try { - md = MessageDigest.getInstance("SHA1"); - } - catch (NoSuchAlgorithmException nsae) { - throw new InternalError("SHA1 not supported"); - } - - byte[] sha1Bytes = md.digest(name); - sha1Bytes[6] &= 0x0f; /* clear version */ - sha1Bytes[6] |= 0x50; /* set to version 5 */ - sha1Bytes[8] &= 0x3f; /* clear variant */ - sha1Bytes[8] |= 0x80; /* set to IETF variant */ - - long msb = 0; - long lsb = 0; - - // NOTE: According to RFC 4122, only first 16 bytes are used, meaning - // bytes 17-20 in the 160 bit SHA1 hash are simply discarded in this case... - for (int i=0; i<8; i++) { - msb = (msb << 8) | (sha1Bytes[i] & 0xff); - } - for (int i=8; i<16; i++) { - lsb = (lsb << 8) | (sha1Bytes[i] & 0xff); - } - - return new UUID(msb, lsb); - } - - /** - * Creates a version 1 time (and node) based {@code UUID}. - * The node part is by default the IEE 802 (mac) address of one of the network cards of the current machine. - * - * @return a {@code UUID} based on the current time and the node address of this computer. - * @see RFC 4122 4.2. Algorithms for Creating a Time-Based UUID - * @see IEEE 802 (mac) address - * @see Overriding the node address - * - * @throws IllegalStateException if the IEEE 802 (mac) address of the computer (node) cannot be found. - */ - public static UUID timeNodeBasedUUID() { - if (MAC_ADDRESS_NODE == -1) { - throw new IllegalStateException("Could not determine IEEE 802 (mac) address for node"); - } - - return createTimeBasedUUIDforNode(MAC_ADDRESS_NODE); - } - - /** - * Creates a version 1 time based {@code UUID} with the node part replaced by a random based value. - * The node part is computed using a 47 bit secure random number + lsb of first octet (unicast/multicast bit) set to 1. - * These {@code UUID}s can never clash with "real" node based version 1 {@code UUID}s due to the difference in - * the unicast/multicast bit, however, no uniqueness between multiple machines/vms/nodes can be guaranteed. - * - * @return a {@code UUID} based on the current time and a random generated "node" value. - * @see RFC 4122 4.5. Node IDs that Do Not Identify the Host - * @see RFC 4122 Appendix A - * @see Lifetime of random node value - * - * @throws IllegalStateException if the IEEE 802 (mac) address of the computer (node) cannot be found. - */ - public static UUID timeRandomBasedUUID() { - return createTimeBasedUUIDforNode(SECURE_RANDOM_NODE); - } - - private static UUID createTimeBasedUUIDforNode(final long node) { - return new UUID(createTimeAndVersion(), createClockSeqAndNode(node)); - } - - // TODO: Version 2 UUID? - /* - Version 2 UUIDs are similar to Version 1 UUIDs, with the upper byte of the clock sequence replaced by the - identifier for a "local domain" (typically either the "POSIX UID domain" or the "POSIX GID domain") - and the first 4 bytes of the timestamp replaced by the user's POSIX UID or GID (with the "local domain" - identifier indicating which it is).[2][3] - */ - - private static long createClockSeqAndNode(final long node) { - // Variant (2) + Clock seq high and low + node - return 0x8000000000000000l | (Clock.getClockSequence() << 48) | node & 0xffffffffffffl; - } - - private static long createTimeAndVersion() { - long clockTime = Clock.currentTimeHundredNanos(); - - long time = clockTime << 32; // Time low - time |= (clockTime & 0xFFFF00000000L) >> 16; // Time mid - time |= ((clockTime >> 48) & 0x0FFF); // Time high - time |= 0x1000; // Version (1) - - return time; - } - - /** - * Returns a comparator that compares UUIDs as 128 bit unsigned entities, as mentioned in RFC 4122. - * This is different than {@link UUID#compareTo(Object)} that compares the UUIDs as signed entities. - * - * @return a comparator that compares UUIDs as 128 bit unsigned entities. - * - * @see java.lang.UUID compareTo() does not do an unsigned compare - * @see RFC 4122 Appendix A - */ - public static Comparator comparator() { - return COMPARATOR; - } - - static final class UUIDComparator implements Comparator { - public int compare(UUID left, UUID right) { - // The ordering is intentionally set up so that the UUIDs - // can simply be numerically compared as two *UNSIGNED* numbers - if (left.getMostSignificantBits() >>> 32 < right.getMostSignificantBits() >>> 32) { - return -1; - } - else if (left.getMostSignificantBits() >>> 32 > right.getMostSignificantBits() >>> 32) { - return 1; - } - else if ((left.getMostSignificantBits() & 0xffffffffl) < (right.getMostSignificantBits() & 0xffffffffl)) { - return -1; - } - else if ((left.getMostSignificantBits() & 0xffffffffl) > (right.getMostSignificantBits() & 0xffffffffl)) { - return 1; - } - else if (left.getLeastSignificantBits() >>> 32 < right.getLeastSignificantBits() >>> 32) { - return -1; - } - else if (left.getLeastSignificantBits() >>> 32 > right.getLeastSignificantBits() >>> 32) { - return 1; - } - else if ((left.getLeastSignificantBits() & 0xffffffffl) < (right.getLeastSignificantBits() & 0xffffffffl)) { - return -1; - } - else if ((left.getLeastSignificantBits() & 0xffffffffl) > (right.getLeastSignificantBits() & 0xffffffffl)) { - return 1; - } - - return 0; - } - } - - /** - * A high-resolution timer for use in creating version 1 {@code UUID}s. - */ - static final class Clock { - // Java: 0:00, Jan. 1st, 1970 vs UUID: 0:00, Oct 15th, 1582 - private static final long JAVA_EPOCH_OFFSET_HUNDRED_NANOS = 122192928000000000L; - - private static int clockSeq = SECURE_RANDOM.nextInt(); - - private static long initialNanos; - private static long initialTime; - - private static long lastMeasuredTime; - private static long lastTime; - - static { - initClock(); - } - - private static void initClock() { - long millis = System.currentTimeMillis(); - long nanos = System.nanoTime(); - - initialTime = JAVA_EPOCH_OFFSET_HUNDRED_NANOS + millis * 10000 + (nanos / 100) % 10000; - initialNanos = nanos; - } - - public static synchronized long currentTimeHundredNanos() { - // Measure delta since init and compute accurate time - long time; - - while ((time = initialTime + (System.nanoTime() - initialNanos) / 100) < lastMeasuredTime) { - // Reset clock seq (should happen VERY rarely) - initClock(); - clockSeq++; - } - - lastMeasuredTime = time; - - if (time <= lastTime) { - // This typically means the clock isn't accurate enough, use auto-incremented time. - // It is possible that more timestamps than available are requested for - // each time unit in the system clock, but that is extremely unlikely. - // TODO: RFC 4122 says we should wait in the case of too many requests... - time = ++lastTime; - } - else { - lastTime = time; - } - - return time; - } - - public static synchronized long getClockSequence() { - return clockSeq & 0x3fff; - } - } - - /** - * Static inner class for 1.5 compatibility. - */ - static final class MacAddressFinder { - public static long[] getMacAddressNodes() { - List nodeAddresses = new ArrayList(); - try { - Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); - - if (interfaces != null) { - while (interfaces.hasMoreElements()) { - NetworkInterface nic = interfaces.nextElement(); - - if (!nic.isVirtual()) { - long nodeAddress = 0; - - byte[] hardware = nic.getHardwareAddress(); // 1.6 method - - if (hardware != null && hardware.length == 6 && hardware[1] != (byte) 0xff) { - // Network byte order - nodeAddress |= (long) (hardware[0] & 0xff) << 40; - nodeAddress |= (long) (hardware[1] & 0xff) << 32; - nodeAddress |= (long) (hardware[2] & 0xff) << 24; - nodeAddress |= (long) (hardware[3] & 0xff) << 16; - nodeAddress |= (long) (hardware[4] & 0xff) << 8; - nodeAddress |= (long) (hardware[5] & 0xff); - - nodeAddresses.add(nodeAddress); - } - } - } - } - } - catch (SocketException ex) { - return null; - } - - long[] unwrapped = new long[nodeAddresses.size()]; - for (int i = 0, nodeAddressesSize = nodeAddresses.size(); i < nodeAddressesSize; i++) { - unwrapped[i] = nodeAddresses.get(i); - } - - return unwrapped; - } - } -} diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/XMLProperties.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/XMLProperties.java deleted file mode 100755 index 40b464cb..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/XMLProperties.java +++ /dev/null @@ -1,1287 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.util; - -import com.twelvemonkeys.lang.StringUtil; -import com.twelvemonkeys.xml.XMLSerializer; -import org.w3c.dom.*; -import org.xml.sax.*; -import org.xml.sax.helpers.DefaultHandler; -import org.xml.sax.helpers.XMLReaderFactory; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import java.io.*; -import java.lang.reflect.Constructor; -import java.lang.reflect.Modifier; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.*; - -/** - * Properties subclass, that reads and writes files in a simple XML format. - * Can be used in-place where ever {@link java.util.Properties} - * is used. The major differences are that it reads - * and writes XML files, instead of ".properties" format files, and has - * support for typed values (where normal Properties only supports Strings). - *

- * The greatest advantage of the XML format, is that it - * supports hierarchial structures or grouping of properties, in addtition to - * be a more standard way of storing data. The XML format also opens up for - * allowing for more metadata on - * the properties, such as type and the format information, specifying how to - * read and write them. - *

- * This class relies on SAX for reading and parsing XML, in - * addition, it requires DOM for outputting XML. It is possible - * to configure what (SAX implementing) parser to use, by setting the system - * property {@code org.xml.sax.driver} to your favourite SAX parser. The - * default is the {@code org.apache.xerces.parsers.SAXParser}. - *

- * XML Format (DTD):
- *

- * <!ELEMENT properties (property)*>
- * <!ELEMENT property (value?, property*)>
- * <!ATTLIST property
- *                    name   CDATA #REQUIRED
- *                    value  CDATA #IMPLIED
- *                    type   CDATA "String"
- *                    format CDATA #IMPLIED
- * >
- * <!ELEMENT value (PCDATA)>
- * <!ATTLIST value
- *                    type   CDATA "String"
- *                    format CDATA #IMPLIED
- * >
- * 
- * See {@link #SYSTEM_DTD_URI}, {@link #DTD}. - *

- * XML Format eample:
- *
- * <?xml version="1.0" encoding="UTF-8"?>
- * <!DOCTYPE properties SYSTEM "http://www.twelvemonkeys.com/xml/XMLProperties.dtd">
- * <!-- A simple XMLProperties example -->
- * <!-- Sat Jan 05 00:16:55 CET 2002 -->
- * <properties>
- *    <property name="one" value="1" type="Integer" />
- *    <property name="two">
- *       <property name="a" value="A" />
- *       <property name="b">
- *           <value>B is a very long value, that can span several
- * lines
- * <![CDATA[<this><doesn't ---> really
- * matter<
- * ]]>
- * as it is escaped using CDATA.</value>
- *       </property>
- *       <property name="c" value="C">
- *          <property name="i" value="I"/>
- *       </property>
- *    </property>
- *    <property name="date" value="16. Mar 2002"
- *              type="java.util.Date" format="dd. MMM yyyy"/>
- *    <property name="none" value="" />
- * </properties>
- * 
- * Results in the properties {@code one=1, two.a=A, two.b=B is a very long..., - * two.c=C, two.c.i=I, date=Sat Mar 16 00:00:00 CET 2002 - * } and {@code none=}. Note that there is no property named - * {@code two}. - * - * @see java.util.Properties - * @see #setPropertyValue(String,Object) - * @see #getPropertyValue(String) - * @see #load(InputStream) - * @see #store(OutputStream,String) - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/util/XMLProperties.java#1 $ - * - */ -// TODO: Consider deleting this code.. Look at Properties XML format. -public class XMLProperties extends Properties { - - /** {@code "UTF-8"} */ - public final static String UTF_8_ENCODING = "UTF-8"; - - /** {@code "xmlns"} */ - public final static String XMLNS = "xmlns"; - - /** {@code "properties"} */ - public final static String PROPERTIES = "properties"; - - /** {@code "property"} */ - public final static String PROPERTY = "property"; - - /** {@code "name"} */ - public final static String PROPERTY_NAME = "name"; - - /** {@code "value"} */ - public final static String PROPERTY_VALUE = "value"; - - /** {@code "type"} */ - public final static String PROPERTY_TYPE = "type"; - - /** {@code "format"} */ - public final static String PROPERTY_FORMAT = "format"; - - /** {@code "String"} ({@link java.lang.String}) */ - public final static String DEFAULT_TYPE = "String"; - - /** {@code "yyyy-MM-dd hh:mm:ss.SSS"} - * ({@link java.sql.Timestamp} format, excpet nanos) */ - public final static String DEFAULT_DATE_FORMAT = "yyyy-MM-dd hh:mm:ss.SSS"; - - /** This is the DTD */ - public final static String DTD = - "\n\n\n\n"; - - /** {@code "http://www.twelvemonkeys.com/xml/XMLProperties.dtd"} */ - public final static String SYSTEM_DTD_URI = "http://www.twelvemonkeys.com/xml/XMLProperties.dtd"; - - /** {@code "http://www.twelvemonkeys.com/xml/XMLProperties"} */ - public final static String NAMESPACE_URI = "http://www.twelvemonkeys.com/xml/XMLProperties"; - - /** {@code "http://xml.org/sax/features/validation"} */ - public final static String SAX_VALIDATION_URI = "http://xml.org/sax/features/validation"; - - /** debug */ - private boolean mValidation = true; - protected Vector mErrors = null; - protected Vector mWarnings = null; - - // protected Hashtable mTypes = new Hashtable(); - protected Hashtable mFormats = new Hashtable(); - protected static DateFormat sDefaultFormat = new SimpleDateFormat(DEFAULT_DATE_FORMAT); - - /** - * Creates an empty property list with no default values. - */ - public XMLProperties() {} - - /** - * Creates an empty property list with the specified defaults. - * - * @param pDefaults the defaults. - */ - public XMLProperties(Properties pDefaults) { - - // Sets the protected defaults variable - super(pDefaults); - } - - void addXMLError(SAXParseException pException) { - - if (mErrors == null) { - mErrors = new Vector(); - } - mErrors.add(pException); - } - - /** - * Gets the non-fatal XML errors (SAXParseExceptions) resulting from a - * load. - * - * @return An array of SAXParseExceptions, or null if none occured. - * - * @see XMLProperties.PropertiesHandler - * @see #load(InputStream) - */ - public SAXParseException[] getXMLErrors() { - - if (mErrors == null) { - return null; - } - return (SAXParseException[]) mErrors.toArray(new SAXParseException[mErrors.size()]); - } - - void addXMLWarning(SAXParseException pException) { - - if (mWarnings == null) { - mWarnings = new Vector(); - } - mWarnings.add(pException); - } - - /** - * Gets the XML warnings (SAXParseExceptions) resulting from a load. - * - * @return An array of SAXParseExceptions, or null if none occured. - * - * @see XMLProperties.PropertiesHandler - * @see #load(InputStream) - */ - public SAXParseException[] getXMLWarnings() { - - if (mWarnings == null) { - return null; - } - return (SAXParseException[]) mWarnings.toArray(new SAXParseException[mWarnings.size()]); - } - - /** - * Reads a property list (key and element pairs) from the input stream. The - * stream is assumed to be using the UFT-8 character encoding, and be in - * valid, well-formed XML format. - *

- * After loading, any errors or warnings from the SAX parser, are available - * as array of SAXParseExceptions from the getXMLErrors and getXMLWarnings - * methods. - * - * @param pInput the input stream to load from. - * - * @exception IOException if an error occurred when reading from the input - * stream. Any SAXExceptions are also wrapped in IOExceptions. - * - * @see Properties#load(InputStream) - * @see #DTD - * @see #SYSTEM_DTD_URI - * @see XMLProperties.PropertiesHandler - * @see #getXMLErrors - * @see #getXMLWarnings - */ - public synchronized void load(InputStream pInput) throws IOException { - // Get parser instance - XMLReader parser; - - // Try to instantiate System default parser - String driver = System.getProperty("org.xml.sax.driver"); - - if (driver == null) { - - // Instantiate the org.apache.xerces.parsers.SAXParser as default - driver = "org.apache.xerces.parsers.SAXParser"; - } - try { - parser = XMLReaderFactory.createXMLReader(driver); - parser.setFeature(SAX_VALIDATION_URI, mValidation); - } catch (SAXNotRecognizedException saxnre) { - - // It should be okay to throw RuntimeExptions, as you will need an - // XML parser - throw new RuntimeException("Error configuring XML parser \"" + driver + "\": " + saxnre.getClass().getName() + ": " - + saxnre.getMessage()); - } catch (SAXException saxe) { - throw new RuntimeException("Error creating XML parser \"" + driver + "\": " + saxe.getClass().getName() + ": " + saxe.getMessage()); - } - - // Register handler - PropertiesHandler handler = new PropertiesHandler(this); - - parser.setContentHandler(handler); - parser.setErrorHandler(handler); - parser.setDTDHandler(handler); - parser.setEntityResolver(handler); - - // Read and parse XML - try { - parser.parse(new InputSource(pInput)); - } catch (SAXParseException saxpe) { - - // Wrap SAXException in IOException to be consistent - throw new IOException("Error parsing XML: " + saxpe.getClass().getName() + ": " + saxpe.getMessage() + " Line: " - + saxpe.getLineNumber() + " Column: " + saxpe.getColumnNumber()); - } catch (SAXException saxe) { - - // Wrap SAXException in IOException to be consistent - // Doesn't realy matter, as the SAXExceptions seems to be pretty - // meaningless themselves... - throw new IOException("Error parsing XML: " + saxe.getClass().getName() + ": " + saxe.getMessage()); - } - } - - /** - * Initializes the value of a property. - * - * @todo move init code to the parser? - * - * @throws ClassNotFoundException if there is no class found for the given - * type - * @throws IllegalArgumentException if the value given, is not parseable - * as the given type - */ - protected Object initPropertyValue(String pValue, String pType, String pFormat) throws ClassNotFoundException { - - // System.out.println("pValue=" + pValue + " pType=" + pType - // + " pFormat=" + pFormat); - // No value to convert - if (pValue == null) { - return null; - } - - // No conversion needed for Strings - if ((pType == null) || pType.equals("String") || pType.equals("java.lang.String")) { - return pValue; - } - Object value; - - if (pType.equals("Date") || pType.equals("java.util.Date")) { - - // Special parser needed - try { - - // Parse date through StringUtil - if (pFormat == null) { - value = StringUtil.toDate(pValue, sDefaultFormat); - } else { - value = StringUtil.toDate(pValue, new SimpleDateFormat(pFormat)); - } - } catch (IllegalArgumentException e) { - - // Not parseable... - throw e; - } - - // Return - return value; - } else if (pType.equals("java.sql.Timestamp")) { - - // Special parser needed - try { - - // Parse timestamp through StringUtil - value = StringUtil.toTimestamp(pValue); - } catch (IllegalArgumentException e) { - - // Not parseable... - throw new RuntimeException(e.getMessage()); - } - - // Return - return value; - } else { - int dot = pType.indexOf("."); - - if (dot < 0) { - pType = "java.lang." + pType; - } - - // Get class - Class cl = Class.forName(pType); - - // Try to create instance from (String) - value = createInstance(cl, pValue); - if (value == null) { - - // createInstance failed for some reason - // Try to invoke the static method valueof(String) - value = invokeStaticMethod(cl, "valueOf", pValue); - - // If the value is still null, well, then I cannot help... - } - } - - // Return - return value; - } - - /** - * Creates an object from the given class' single argument constructor. - * - * @return The object created from the constructor. - * If the constructor could not be invoked for any reason, null is - * returned. - */ - private Object createInstance(Class pClass, Object pParam) { - Object value; - - try { - - // Create param and argument arrays - Class[] param = { pParam.getClass() }; - Object[] arg = { pParam }; - - // Get constructor - Constructor constructor = pClass.getDeclaredConstructor(param); - - // Invoke and create instance - value = constructor.newInstance(arg); - } catch (Exception e) { - return null; - } - return value; - } - - /** - * Creates an object from any given static method, given the parameter - * - * @return The object returned by the static method. - * If the return type of the method is a primitive type, it is wrapped in - * the corresponding wrapper object (int is wrapped in an Integer). - * If the return type of the method is void, null is returned. - * If the method could not be invoked for any reason, null is returned. - */ - private Object invokeStaticMethod(Class pClass, String pMethod, Object pParam) { - Object value = null; - - try { - - // Create param and argument arrays - Class[] param = { pParam.getClass() }; - Object[] arg = { pParam }; - - // Get method - // *** If more than one such method is found in the class, and one - // of these methods has a RETURN TYPE that is more specific than - // any of the others, that method is reflected; otherwise one of - // the methods is chosen ARBITRARILY. - // java/lang/Class.html#getMethod(java.lang.String, java.lang.Class[]) - java.lang.reflect.Method method = pClass.getMethod(pMethod, param); - - // Invoke public static method - if (Modifier.isPublic(method.getModifiers()) && Modifier.isStatic(method.getModifiers())) { - value = method.invoke(null, arg); - } - } catch (Exception e) { - return null; - } - return value; - } - - /** - * Gets the format of a property. This value is used for formatting the - * value before it is stored as xml. - * - * @param pKey a key in this hashtable. - * - * @return the format for the specified key or null if it does not - * have one. - */ - public String getPropertyFormat(String pKey) { - - // Get format - return StringUtil.valueOf(mFormats.get(pKey)); - } - - /** - * Sets the format of a property. This value is used for formatting the - * value before it is stored as xml. - * - * @param pKey a key in this hashtable. - * @param pFormat a string representation of the format. - * - * @return the previous format for the specified key or null if it did not - * have one. - */ - public synchronized String setPropertyFormat(String pKey, String pFormat) { - - // Insert format - return StringUtil.valueOf(mFormats.put(pKey, pFormat)); - } - - /** - * Calls the Hashtable method put. Provided for parallelism with the - * getPropertyValue method. Enforces use of strings for property keys. - * The value returned is the result of the Hashtable call to put. - * - * @param pKey the key to be placed into this property list. - * @param pValue the value corresponding to key. - * - * @return the previous value of the specified key in this property list, - * or null if it did not have one. - * - * @see #getPropertyValue(String) - */ - public synchronized Object setPropertyValue(String pKey, Object pValue) { - - // Insert value - return put(pKey, pValue); - } - - /** - * Searches for the property with the specified key in this property list. - * If the key is not found in this property list, the default property - * list, and its defaults, recursively, are then checked. The method - * returns null if the property is not found. - * - * @param pKey the property key. - * - * @return the value in this property list with the specified key value. - * - * @see #setPropertyValue(String, Object) - * @see #getPropertyValue(String, Object) - * @see Properties#defaults - */ - public synchronized Object getPropertyValue(String pKey) { - return getPropertyValue(pKey, null); - } - - /** - * Searches for the property with the specified key in this property list. - * If the key is not found in this property list, the default property - * list, and its defaults, recursively, are then checked. The method - * returns the default value argument if the property is not found. - * - * @param pKey the property key. - * @param pDefaultValue the default value. - * - * @return the value in this property list with the specified key value. - * - * @see #getPropertyValue(String) - * @see Properties#defaults - */ - public Object getPropertyValue(String pKey, Object pDefaultValue) { - - Object value = super.get(pKey); // super.get() is EXTREMELEY IMPORTANT - - if (value != null) { - return value; - } - if (defaults instanceof XMLProperties) { - return (((XMLProperties) defaults).getPropertyValue(pKey)); - } - return ((defaults != null) ? defaults.getProperty(pKey) : pDefaultValue); - } - - /** - * Overloaded get method, that always returns Strings. - * Due to the way the store and list methods of - * java.util.Properties works (it calls get and casts to String, instead - * of calling getProperty), this methods returns - * StringUtil.valueOf(super.get), to avoid ClassCastExcpetions. - *

- * If you need the old functionality back, - * getPropertyValue returns super.get directly. - * A cleaner approach would be to override the list and store - * methods, but it's too much work for nothing... - * - * @param pKey a key in this hashtable - * - * @return the value to which the key is mapped in this hashtable, - * converted to a string; null if the key is not mapped to any value in - * this hashtable. - * - * @see #getPropertyValue(String) - * @see Properties#getProperty(String) - * @see Hashtable#get(Object) - * @see StringUtil#valueOf(Object) - */ - public Object get(Object pKey) { - - //System.out.println("get(" + pKey + "): " + super.get(pKey)); - Object value = super.get(pKey); - - // --- - if ((value != null) && (value instanceof Date)) { // Hmm.. This is true for subclasses too... - - // Special threatment of Date - String format = getPropertyFormat(StringUtil.valueOf(pKey)); - - if (format != null) { - value = new SimpleDateFormat(format).format(value); - } else { - value = sDefaultFormat.format(value); - } - return value; - } - - // --- - // Simply return value - return StringUtil.valueOf(value); - } - - /** - * Searches for the property with the specified key in this property list. - * If the key is not found in this property list, the default property list, - * and its defaults, recursively, are then checked. The method returns the - * default value argument if the property is not found. - * - * @param pKey the hashtable key. - * @param pDefaultValue a default value. - * - * @return the value in this property list with the specified key value. - * @see #setProperty - * @see #defaults - */ - public String getProperty(String pKey, String pDefaultValue) { - - // Had to override this because Properties uses super.get()... - String value = (String) get(pKey); // Safe cast, see get(Object) - - if (value != null) { - return value; - } - return ((defaults != null) - ? defaults.getProperty(pKey) - : pDefaultValue); - } - - /** - * Searches for the property with the specified key in this property list. - * If the key is not found in this property list, the default property list, - * and its defaults, recursively, are then checked. The method returns - * {@code null} if the property is not found. - * - * @param pKey the property key. - * @return the value in this property list with the specified key value. - * @see #setProperty - * @see #defaults - */ - public String getProperty(String pKey) { - - // Had to override this because Properties uses super.get()... - return getProperty(pKey, null); - } - - /** - * Writes this property list (key and element pairs) in this - * {@code Properties} - * table to the output stream in a format suitable for loading into a - * Properties table using the load method. This implementation writes - * the list in XML format. The stream is written using the UTF-8 character - * encoding. - * - * @param pOutput the output stream to write to. - * @param pHeader a description of the property list. - * - * @exception IOException if writing this property list to the specified - * output stream throws an IOException. - * - * @see java.util.Properties#store(OutputStream,String) - */ - public synchronized void store(OutputStream pOutput, String pHeader) throws IOException { - storeXML(this, pOutput, pHeader); - } - - /** - * Utility method that stores the property list in normal properties - * format. This method writes the list of Properties (key and element - * pairs) in the given {@code Properties} - * table to the output stream in a format suitable for loading into a - * Properties table using the load method. The stream is written using the - * ISO 8859-1 character encoding. - * - * @param pProperties the Properties table to store - * @param pOutput the output stream to write to. - * @param pHeader a description of the property list. - * - * @exception IOException if writing this property list to the specified - * output stream throws an IOException. - * - * @see java.util.Properties#store(OutputStream,String) - */ - public static void storeProperties(Map pProperties, OutputStream pOutput, String pHeader) throws IOException { - // Create new properties - Properties props = new Properties(); - - // Copy all elements from the pProperties (shallow) - Iterator iterator = pProperties.entrySet().iterator(); - - while (iterator.hasNext()) { - Map.Entry entry = (Map.Entry) iterator.next(); - - props.setProperty((String) entry.getKey(), StringUtil.valueOf(entry.getValue())); - } - - // Store normal properties - props.store(pOutput, pHeader); - } - - /** - * Utility method that stores the property list in XML format. This method - * writes the list of Properties (key and element pairs) in the given - * {@code Properties} - * table to the output stream in a format suitable for loading into a - * XMLProperties table using the load method. Useful for converting - * Properties into XMLProperties. - * The stream is written using the UTF-8 character - * encoding. - * - * @param pProperties the Properties table to store. - * @param pOutput the output stream to write to. - * @param pHeader a description of the property list. - * - * @exception IOException if writing this property list to the specified - * output stream throws an IOException. - * - * @see #store(OutputStream,String) - * @see java.util.Properties#store(OutputStream,String) - * - * @todo Find correct way of setting namespace URI's - * @todo Store type and format information - */ - public static void storeXML(Map pProperties, OutputStream pOutput, String pHeader) throws IOException { - // Build XML tree (Document) and write - // Find the implementation - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setNamespaceAware(true); - DocumentBuilder builder; - try { - builder = factory.newDocumentBuilder(); - } - catch (ParserConfigurationException e) { - throw (IOException) new IOException(e.getMessage()).initCause(e); - } - DOMImplementation dom = builder.getDOMImplementation(); - - Document document = dom.createDocument(null, PROPERTIES, dom.createDocumentType(PROPERTIES, null, SYSTEM_DTD_URI)); - Element root = document.getDocumentElement(); - - // This is probably not the correct way of setting a default namespace - root.setAttribute(XMLNS, NAMESPACE_URI); - - // Create and insert the normal Properties headers as XML comments - if (pHeader != null) { - document.insertBefore(document.createComment(" " + pHeader + " "), root); - } - document.insertBefore(document.createComment(" " + new Date() + " "), root); - - // Insert elements from the Properties - Iterator iterator = pProperties.entrySet().iterator(); - - while (iterator.hasNext()) { - Map.Entry entry = (Map.Entry) iterator.next(); - String key = (String) entry.getKey(); - Object value = entry.getValue(); - String format = null; - - if (pProperties instanceof XMLProperties) { - format = ((XMLProperties) pProperties).getPropertyFormat(key); - } - insertElement(document, key, value, format); - } - - // Create serializer and output document - //XMLSerializer serializer = new XMLSerializer(pOutput, new OutputFormat(document, UTF_8_ENCODING, true)); - XMLSerializer serializer = new XMLSerializer(pOutput, UTF_8_ENCODING); - - serializer.serialize(document); - } - - /** - * Inserts elements to the given document one by one, and creates all its - * parents if needed. - * - * @param pDocument the document to insert to. - * @param pName the name of the property element. - * @param pValue the value of the property element. - * @param pFormat - * - * @todo I guess this implementation could use some optimisaztion, as - * we do a lot of unneccessary looping. - */ - private static void insertElement(Document pDocument, String pName, Object pValue, String pFormat) { - - // Get names of all elements we need - String[] names = StringUtil.toStringArray(pName, "."); - - // Get value formatted as string - String value = null; - - if (pValue != null) { - // --- - if (pValue instanceof Date) { - - // Special threatment of Date - if (pFormat != null) { - value = new SimpleDateFormat(pFormat).format(pValue); - } - else { - value = sDefaultFormat.format(pValue); - } - } - else { - value = String.valueOf(pValue); - } - - // --- - } - - // Loop through document from root, and insert parents as needed - Element element = pDocument.getDocumentElement(); - - for (int i = 0; i < names.length; i++) { - boolean found = false; - - // Get children - NodeList children = element.getElementsByTagName(PROPERTY); - Element child = null; - - // Search for correct name - for (int j = 0; j < children.getLength(); j++) { - child = (Element) children.item(j); - if (names[i].equals(child.getAttribute(PROPERTY_NAME))) { - // Found - found = true; - element = child; - break; // Next name - } - } - - // Test if the node was not found, otherwise we need to insert - if (!found) { - // Not found - child = pDocument.createElement(PROPERTY); - child.setAttribute(PROPERTY_NAME, names[i]); - - // Insert it - element.appendChild(child); - element = child; - } - - // If it's the destination node, set the value - if ((i + 1) == names.length) { - - // If the value string contains special data, - // use a CDATA block instead of the "value" attribute - if (StringUtil.contains(value, "\n") || StringUtil.contains(value, "\t") || StringUtil.contains(value, "\"") - || StringUtil.contains(value, "&") || StringUtil.contains(value, "<") || StringUtil.contains(value, ">")) { - - // Create value element - Element valueElement = pDocument.createElement(PROPERTY_VALUE); - - // Set type attribute - String className = pValue.getClass().getName(); - - className = StringUtil.replace(className, "java.lang.", ""); - if (!DEFAULT_TYPE.equals(className)) { - valueElement.setAttribute(PROPERTY_TYPE, className); - } - - // Set format attribute - if (pFormat != null) { - valueElement.setAttribute(PROPERTY_FORMAT, pFormat); - } - - // Crate cdata section - CDATASection cdata = pDocument.createCDATASection(value); - - // Append to document tree - valueElement.appendChild(cdata); - child.appendChild(valueElement); - } - else { - // Just set normal attribute value - child.setAttribute(PROPERTY_VALUE, value); - - // Set type attribute - String className = pValue.getClass().getName(); - - className = StringUtil.replace(className, "java.lang.", ""); - if (!DEFAULT_TYPE.equals(className)) { - child.setAttribute(PROPERTY_TYPE, className); - } - - // If format is set, store in attribute - if (pFormat != null) { - child.setAttribute(PROPERTY_FORMAT, pFormat); - } - } - } - } - } - - /** - * Gets all properties in a properties group. - * If no properties exists in the specified group, {@code null} is - * returned. - * - * @param pGroupKey the group key - * - * @return a new Properties continaing all properties in the group. Keys in - * the new Properties wil not contain the group key. - * If no properties exists in the specified group, {@code null} is - * returned. - */ - public Properties getProperties(String pGroupKey) { - // Stupid impl... - XMLProperties props = new XMLProperties(); - String groupKey = pGroupKey; - - if (groupKey.charAt(groupKey.length()) != '.') { - groupKey += "."; - } - - Iterator iterator = entrySet().iterator(); - - while (iterator.hasNext()) { - Map.Entry entry = (Map.Entry) iterator.next(); - String key = (String) entry.getKey(); - - if (key.startsWith(groupKey)) { - String subKey = key.substring(key.indexOf(groupKey)); - - props.setPropertyValue(subKey, entry.getValue()); - } - } - - return ((props.size() > 0) ? props : null); - } - - /** - * Sets the properties in the given properties group. - * Existing properties in the same group, will not be removed, unless they - * are replaced by new values. - * Any existing properties in the same group that was replaced, are - * returned. If no properties are replaced, null is - * returned. - * - * @param pGroupKey the group key - * @param pProperties the properties to set into this group - * - * @return Any existing properties in the same group that was replaced. - * If no properties are replaced, null is - * returned. - */ - public Properties setProperties(String pGroupKey, Properties pProperties) { - XMLProperties old = new XMLProperties(); - String groupKey = pGroupKey; - - if (groupKey.charAt(groupKey.length()) != '.') { - groupKey += "."; - } - Iterator iterator = pProperties.entrySet().iterator(); - - while (iterator.hasNext()) { - Map.Entry entry = (Map.Entry) iterator.next(); - String key = (String) entry.getKey(); - Object obj = setPropertyValue(groupKey + key, entry.getValue()); - - // Return removed entries - if (obj != null) { - old.setPropertyValue(groupKey + key, entry.getValue()); - } - } - return ((old.size() > 0) ? old : null); - } - - /** - * For testing only. - */ - public static void main(String[] pArgs) throws Exception { - // -- Print DTD - System.out.println("DTD: \n" + DTD); - System.out.println("--"); - - // -- Test load - System.out.println("Reading properties from \"" + pArgs[0] + "\"..."); - XMLProperties props = new XMLProperties(); - - props.load(new FileInputStream(new File(pArgs[0]))); - props.list(System.out); - System.out.println("--"); - - // -- Test recursion - String key = "key"; - Object old = props.setProperty(key, "AAA"); - Properties p1 = new XMLProperties(new XMLProperties(props)); - Properties p2 = new Properties(new Properties(props)); - - System.out.println("XMLProperties: " + p1.getProperty(key) + " ==" + " Properties: " + p2.getProperty(key)); - if (old == null) { - props.remove("key"); - } else { - props.put("key", old); // Put old value back, to avoid confusion... - } - System.out.println("--"); - - // -- Test store - //props.store(System.out, "XML Properties file written by XMLProperties."); - File out = new File("copy_of_" + pArgs[0]); - - System.out.println("Writing properties to \"" + out.getName() + "\""); - if (!out.exists()) { - props.store(new FileOutputStream(out), "XML Properties file written by XMLProperties."); - } else { - System.err.println("File \"" + out.getName() + "\" allready exists, cannot write!"); - } - - // -- Test utility methods - // Write normal properties from XMLProperties - out = new File("copy_of_" + pArgs[0].substring(0, pArgs[0].lastIndexOf(".")) + ".properties"); - System.out.println("Writing properties to \"" + out.getName() + "\""); - if (!out.exists()) { - storeProperties(props, new FileOutputStream(out), "Properties file written by XMLProperties."); - } else { - System.err.println("File \"" + out.getName() + "\" allready exists, cannot write!"); - } - System.out.println("--"); - - // -- Test type attribute - System.out.println("getPropertyValue(\"one\"): " + props.getPropertyValue("one") + " class: " - + props.getPropertyValue("one").getClass()); - System.out.println("setPropertyValue(\"now\", " + new Date() + "): " + props.setPropertyValue("now", new Date()) + " class: " - + props.getPropertyValue("now").getClass()); - System.out.println("getPropertyValue(\"date\"): " + props.getPropertyValue("date") + " class: " - + props.getPropertyValue("date").getClass()); - System.out.println("getPropertyValue(\"time\"): " + props.getPropertyValue("time") + " class: " - + props.getPropertyValue("time").getClass()); - } - - /** - * ContentHandler, ErrorHandler and EntityResolver implementation for the - * SAX Parser. - */ - protected class PropertiesHandler extends DefaultHandler { - protected Stack mStack = null; - - /** Stores the characters read so far, from the characters callback */ - protected char[] mReadSoFar = null; - protected boolean mIsValue = false; - protected String mType = null; - protected String mFormat = null; - protected XMLProperties mProperties = null; - protected Locator mLocator = null; - - /** - * Creates a PropertiesHandler for the given XMLProperties. - */ - PropertiesHandler(XMLProperties pProperties) { - mProperties = pProperties; - mStack = new Stack(); - } - - /** - * setDocumentLocator implementation. - */ - public void setDocumentLocator(Locator pLocator) { - - // System.out.println("Setting locator: " + pLocator); - mLocator = pLocator; - } - - /** - * Calls XMLProperties.addXMLError with the given SAXParseException - * as the argument. - */ - public void error(SAXParseException pException) throws SAXParseException { - - //throw pException; - mProperties.addXMLError(pException); - - /* - System.err.println("error: " + pException.getMessage()); - System.err.println("line: " + mLocator.getLineNumber()); - System.err.println("column: " + mLocator.getColumnNumber()); - */ - } - - /** - * Throws the given SAXParseException (and stops the parsing). - */ - public void fatalError(SAXParseException pException) throws SAXParseException { - - throw pException; - - /* - System.err.println("fatal error: " + pException.getMessage()); - System.err.println("line: " + mLocator.getLineNumber()); - System.err.println("column: " + mLocator.getColumnNumber()); - */ - } - - /** - * Calls XMLProperties.addXMLWarning with the given SAXParseException - * as the argument. - */ - public void warning(SAXParseException pException) throws SAXParseException { - - // throw pException; - mProperties.addXMLWarning(pException); - - /* - System.err.println("warning: " + pException.getMessage()); - System.err.println("line: " + mLocator.getLineNumber()); - System.err.println("column: " + mLocator.getColumnNumber()); - */ - } - - /** - * startElement implementation. - */ - public void startElement(String pNamespaceURI, String pLocalName, String pQualifiedName, Attributes pAttributes) throws SAXException { - - /* - - String attributes = ""; - for (int i = 0; i < pAttributes.getLength(); i++) { - attributes += pAttributes.getQName(i) + "=" + pAttributes.getValue(i) + (i < pAttributes.getLength() ? ", " : ""); - } - - System.out.println("startElement: " + pNamespaceURI - + "." + pLocalName - + " (" + pQualifiedName + ") " - + attributes); - */ - if (XMLProperties.PROPERTY.equals(pLocalName)) { - - // Get attibute values - String name = pAttributes.getValue(XMLProperties.PROPERTY_NAME); - String value = pAttributes.getValue(XMLProperties.PROPERTY_VALUE); - String type = pAttributes.getValue(XMLProperties.PROPERTY_TYPE); - String format = pAttributes.getValue(XMLProperties.PROPERTY_FORMAT); - - // Get the full name of the property - if (!mStack.isEmpty()) { - name = (String) mStack.peek() + "." + name; - } - - // Set the property - if (value != null) { - mProperties.setProperty(name, value); - - // Store type & format - if (!XMLProperties.DEFAULT_TYPE.equals(type)) { - mType = type; - mFormat = format; // Might be null (no format) - } - } - - // Push the last name on the stack - mStack.push(name); - } // /PROPERTY - else if (XMLProperties.PROPERTY_VALUE.equals(pLocalName)) { - - // Get attibute values - String name = (String) mStack.peek(); - String type = pAttributes.getValue(XMLProperties.PROPERTY_TYPE); - String format = pAttributes.getValue(XMLProperties.PROPERTY_FORMAT); - - // Store type & format - if (!XMLProperties.DEFAULT_TYPE.equals(type)) { - mType = type; - mFormat = format; - } - mIsValue = true; - } - } - - /** - * endElement implementation. - */ - public void endElement(String pNamespaceURI, String pLocalName, String pQualifiedName) throws SAXException { - - /* - System.out.println("endElement: " + pNamespaceURI - + "." + pLocalName + " (" + pQualifiedName + ")"); - */ - if (XMLProperties.PROPERTY.equals(pLocalName)) { - - // Just remove the last name - String name = (String) mStack.pop(); - - // Init typed values - try { - String prop = mProperties.getProperty(name); - - // Value may be null, if so just skip - if (prop != null) { - Object value = mProperties.initPropertyValue(prop, mType, mFormat); - - // Store format - if ((mFormat != null) &&!XMLProperties.DEFAULT_DATE_FORMAT.equals(mFormat)) { - mProperties.setPropertyFormat(name, mFormat); - } - - //System.out.println("-->" + prop + "-->" + value); - mProperties.setPropertyValue(name, value); - } - - // Clear type & format - mType = null; - mFormat = null; - } catch (Exception e) { - e.printStackTrace(System.err); - throw new SAXException(e); - } - } else if (XMLProperties.PROPERTY_VALUE.equals(pLocalName)) { - if (mStack.isEmpty()) { - - // There can't be any characters here, really - return; - } - - // Get the full name of the property - String name = (String) mStack.peek(); - - // Set the property - String value = new String(mReadSoFar); - - //System.err.println("characters: >" + value+ "<"); - if (!StringUtil.isEmpty(value)) { - - // If there is allready a value, both the value attribute - // and element have been specified, this is an error - if (mProperties.containsKey(name)) { - throw new SAXParseException( - "Value can only be specified either using the \"value\" attribute, OR the \"value\" element, not both.", mLocator); - } - - // Finally, set the property - mProperties.setProperty(name, value); - } - - // Done value processing - mIsValue = false; - } - } - - /** - * characters implementation - */ - public void characters(char[] pChars, int pStart, int pLength) throws SAXException { - // TODO: Use StringBuilder instead? - if (mIsValue) { - // If nothing read so far - if (mReadSoFar == null) { - // Create new array and copy into - mReadSoFar = new char[pLength]; - System.arraycopy(pChars, pStart, mReadSoFar, 0, pLength); - } - else { - // Merge arrays - mReadSoFar = (char[]) CollectionUtil.mergeArrays(mReadSoFar, 0, mReadSoFar.length, pChars, pStart, pLength); - } - } - } - - - /** - * Intercepts the entity - * "http://www.twelvemonkeys.com/xml/XMLProperties.dtd", and return - * an InputSource based on the internal DTD of XMLProperties instead. - * - * @todo Maybe intercept a PUBLIC DTD and be able to have SYSTEM DTD - * override? - */ - public InputSource resolveEntity(String pPublicId, String pSystemId) { - // If we are looking for the standard SYSTEM DTD, then - // Return an InputSource based on the internal DTD. - if (XMLProperties.SYSTEM_DTD_URI.equals(pSystemId)) { - return new InputSource(new StringReader(XMLProperties.DTD)); - } - - // use the default behaviour - return null; - } - } -} - diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/regex/REWildcardStringParser.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/regex/REWildcardStringParser.java deleted file mode 100755 index 0f56c8fc..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/util/regex/REWildcardStringParser.java +++ /dev/null @@ -1,398 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.util.regex; - -import com.twelvemonkeys.util.DebugUtil; - -import java.io.PrintStream; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; - -/** - * This class parses arbitrary strings against a wildcard string mask provided. - * The wildcard characters are '*' and '?'. - *

- * The string masks provided are treated as case sensitive.
- * Null-valued string masks as well as null valued strings to be parsed, will lead to rejection. - * - *


- * - * This task is performed based on regular expression techniques. - * The possibilities of string generation with the well-known wildcard characters stated above, - * represent a subset of the possibilities of string generation with regular expressions.
- * The '*' corresponds to ([Union of all characters in the alphabet])*
- * The '?' corresponds to ([Union of all characters in the alphabet])
- *       These expressions are not suited for textual representation at all, I must say. Is there any math tags included in HTML? - * - *

- * - * This class uses the Regexp package from Apache's Jakarta Project, links below. - * - *


- * - * Examples of usage:
- * This example will return "Accepted!". - *

- * REWildcardStringParser parser = new REWildcardStringParser("*_28????.jp*");
- * if (parser.parseString("gupu_280915.jpg")) {
- *     System.out.println("Accepted!");
- * } else {
- *     System.out.println("Not accepted!");
- * }
- * 
- * - *


- * - * @author Eirik Torske - * @see Jakarta Regexp - * @see {@code org.apache.regexp.RE} - * @see com.twelvemonkeys.util.regex.WildcardStringParser - * - * @todo Rewrite to use this regex package, and not Jakarta directly! - */ -public class REWildcardStringParser /*extends EntityObject*/ { - - // Constants - - /** Field ALPHABET */ - public static final char[] ALPHABET = { - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '\u00e6', - '\u00f8', '\u00e5', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'N', 'M', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', - 'Z', '\u00c6', '\u00d8', '\u00c5', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '_', '-' - }; - - /** Field FREE_RANGE_CHARACTER */ - public static final char FREE_RANGE_CHARACTER = '*'; - - /** Field FREE_PASS_CHARACTER */ - public static final char FREE_PASS_CHARACTER = '?'; - - // Members - Pattern mRegexpParser; - String mStringMask; - boolean mInitialized = false; - int mTotalNumberOfStringsParsed; - boolean mDebugging; - PrintStream out; - - // Properties - // Constructors - - /** - * Creates a wildcard string parser. - *

- * @param pStringMask the wildcard string mask. - */ - public REWildcardStringParser(final String pStringMask) { - this(pStringMask, false); - } - - /** - * Creates a wildcard string parser. - *

- * @param pStringMask the wildcard string mask. - * @param pDebugging {@code true} will cause debug messages to be emitted to {@code System.out}. - */ - public REWildcardStringParser(final String pStringMask, final boolean pDebugging) { - this(pStringMask, pDebugging, System.out); - } - - /** - * Creates a wildcard string parser. - *

- * @param pStringMask the wildcard string mask. - * @param pDebugging {@code true} will cause debug messages to be emitted. - * @param pDebuggingPrintStream the {@code java.io.PrintStream} to which the debug messages will be emitted. - */ - public REWildcardStringParser(final String pStringMask, final boolean pDebugging, final PrintStream pDebuggingPrintStream) { - - this.mStringMask = pStringMask; - this.mDebugging = pDebugging; - this.out = pDebuggingPrintStream; - mInitialized = buildRegexpParser(); - } - - // Methods - - /** - * Converts wildcard string mask to regular expression. - * This method should reside in som utility class, but I don't know how proprietary the regular expression format is... - * @return the corresponding regular expression or {@code null} if an error occurred. - */ - private String convertWildcardExpressionToRegularExpression(final String pWildcardExpression) { - - if (pWildcardExpression == null) { - if (mDebugging) { - out.println(DebugUtil.getPrefixDebugMessage(this) + "wildcard expression is null - also returning null as regexp!"); - } - return null; - } - StringBuilder regexpBuffer = new StringBuilder(); - boolean convertingError = false; - - for (int i = 0; i < pWildcardExpression.length(); i++) { - if (convertingError) { - return null; - } - - // Free-range character '*' - char stringMaskChar = pWildcardExpression.charAt(i); - - if (isFreeRangeCharacter(stringMaskChar)) { - regexpBuffer.append("(([a-�A-�0-9]|.|_|-)*)"); - } - - // Free-pass character '?' - else if (isFreePassCharacter(stringMaskChar)) { - regexpBuffer.append("([a-�A_�0-9]|.|_|-)"); - } - - // Valid characters - else if (isInAlphabet(stringMaskChar)) { - regexpBuffer.append(stringMaskChar); - } - - // Invalid character - aborting - else { - if (mDebugging) { - out.println(DebugUtil.getPrefixDebugMessage(this) - + "one or more characters in string mask are not legal characters - returning null as regexp!"); - } - convertingError = true; - } - } - return regexpBuffer.toString(); - } - - /** - * Builds the regexp parser. - */ - private boolean buildRegexpParser() { - - // Convert wildcard string mask to regular expression - String regexp = convertWildcardExpressionToRegularExpression(mStringMask); - - if (regexp == null) { - out.println(DebugUtil.getPrefixErrorMessage(this) - + "irregularity in regexp conversion - now not able to parse any strings, all strings will be rejected!"); - return false; - } - - // Instantiate a regular expression parser - try { - mRegexpParser = Pattern.compile(regexp); - } - catch (PatternSyntaxException e) { - if (mDebugging) { - out.println(DebugUtil.getPrefixErrorMessage(this) + "RESyntaxException \"" + e.getMessage() - + "\" caught - now not able to parse any strings, all strings will be rejected!"); - } - if (mDebugging) { - e.printStackTrace(System.err); - } - return false; - } - if (mDebugging) { - out.println(DebugUtil.getPrefixDebugMessage(this) + "regular expression parser from regular expression " + regexp - + " extracted from wildcard string mask " + mStringMask + "."); - } - return true; - } - - /** - * Simple check of the string to be parsed. - */ - private boolean checkStringToBeParsed(final String pStringToBeParsed) { - - // Check for nullness - if (pStringToBeParsed == null) { - if (mDebugging) { - out.println(DebugUtil.getPrefixDebugMessage(this) + "string to be parsed is null - rejection!"); - } - return false; - } - - // Check if valid character (element in alphabet) - for (int i = 0; i < pStringToBeParsed.length(); i++) { - if (!isInAlphabet(pStringToBeParsed.charAt(i))) { - if (mDebugging) { - out.println(DebugUtil.getPrefixDebugMessage(this) - + "one or more characters in string to be parsed are not legal characters - rejection!"); - } - return false; - } - } - return true; - } - - /** - * Tests if a certain character is a valid character in the alphabet that is applying for this automaton. - */ - public static boolean isInAlphabet(final char pCharToCheck) { - - for (int i = 0; i < ALPHABET.length; i++) { - if (pCharToCheck == ALPHABET[i]) { - return true; - } - } - return false; - } - - /** - * Tests if a certain character is the designated "free-range" character ('*'). - */ - public static boolean isFreeRangeCharacter(final char pCharToCheck) { - return pCharToCheck == FREE_RANGE_CHARACTER; - } - - /** - * Tests if a certain character is the designated "free-pass" character ('?'). - */ - public static boolean isFreePassCharacter(final char pCharToCheck) { - return pCharToCheck == FREE_PASS_CHARACTER; - } - - /** - * Tests if a certain character is a wildcard character ('*' or '?'). - */ - public static boolean isWildcardCharacter(final char pCharToCheck) { - return ((isFreeRangeCharacter(pCharToCheck)) || (isFreePassCharacter(pCharToCheck))); - } - - /** - * Gets the string mask that was used when building the parser atomaton. - *

- * @return the string mask used for building the parser automaton. - */ - public String getStringMask() { - return mStringMask; - } - - /** - * Parses a string. - *

- * - * @param pStringToBeParsed - * @return {@code true} if and only if the string are accepted by the parser. - */ - public boolean parseString(final String pStringToBeParsed) { - - if (mDebugging) { - out.println(); - } - if (mDebugging) { - out.println(DebugUtil.getPrefixDebugMessage(this) + "parsing \"" + pStringToBeParsed + "\"..."); - } - - // Update statistics - mTotalNumberOfStringsParsed++; - - // Check string to be parsed - if (!checkStringToBeParsed(pStringToBeParsed)) { - return false; - } - - // Perform parsing and return accetance/rejection flag - if (mInitialized) { - return mRegexpParser.matcher(pStringToBeParsed).matches(); - } else { - out.println(DebugUtil.getPrefixErrorMessage(this) + "trying to use non-initialized parser - string rejected!"); - } - return false; - } - - /* - * Overriding mandatory methods from EntityObject's. - */ - - /** - * Method toString - * - * - * @return - * - */ - public String toString() { - - StringBuilder buffer = new StringBuilder(); - - buffer.append(DebugUtil.getClassName(this)); - buffer.append(": String mask "); - buffer.append(mStringMask); - buffer.append("\n"); - return buffer.toString(); - } - - // Just taking the lazy, easy and dangerous way out - - /** - * Method equals - * - * - * @param pObject - * - * @return - * - */ - public boolean equals(Object pObject) { - - if (pObject instanceof REWildcardStringParser) { - REWildcardStringParser externalParser = (REWildcardStringParser) pObject; - - return (externalParser.mStringMask == this.mStringMask); - } - return ((Object) this).equals(pObject); - } - - // Just taking the lazy, easy and dangerous way out - - /** - * Method hashCode - * - * - * @return - * - */ - public int hashCode() { - return ((Object) this).hashCode(); - } - - protected Object clone() throws CloneNotSupportedException { - return new REWildcardStringParser(mStringMask); - } - - // Just taking the lazy, easy and dangerous way out - protected void finalize() throws Throwable {} -} - - -/*--- Formatted in Sun Java Convention Style on ma, des 1, '03 ---*/ - - -/*------ Formatted by Jindent 3.23 Basic 1.0 --- http://www.jindent.de ------*/ diff --git a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/xml/XMLReader.java b/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/xml/XMLReader.java deleted file mode 100755 index a10affe9..00000000 --- a/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/xml/XMLReader.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.xml; - -import java.io.Reader; -import java.io.IOException; - -/** - * XMLReader - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/xml/XMLReader.java#1 $ - */ -public class XMLReader extends Reader { - // TODO: - // Create a reader backed by a pushback(?) inputstream - // Check for Unicode byte order marks - // Otherwise, use pi - // Or.. Just snatch the code form ROME.. ;-) - - public void close() throws IOException { - throw new UnsupportedOperationException("Method close not implemented");// TODO: Implement - } - - public int read(char cbuf[], int off, int len) throws IOException { - throw new UnsupportedOperationException("Method read not implemented");// TODO: Implement - } -} diff --git a/sandbox/sandbox-common/src/test/java/com/twelvemonkeys/image/MappedImageFactoryTest.java b/sandbox/sandbox-common/src/test/java/com/twelvemonkeys/image/MappedImageFactoryTest.java deleted file mode 100644 index 59b7ad5e..00000000 --- a/sandbox/sandbox-common/src/test/java/com/twelvemonkeys/image/MappedImageFactoryTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.twelvemonkeys.image; - -import org.junit.Test; - -import java.awt.image.BufferedImage; - -import static com.twelvemonkeys.image.MappedImageFactory.createCompatibleMappedImage; -import static com.twelvemonkeys.image.MappedImageFactory.getCompatibleBufferedImageType; -import static org.junit.Assert.assertEquals; - -public class MappedImageFactoryTest { - - @Test - public void testGetCompatibleBufferedImageTypeFromBufferedImage() throws Exception { - for (int type = BufferedImage.TYPE_INT_RGB; type <= BufferedImage.TYPE_BYTE_INDEXED; type++) { // 1 - 13 - assertEquals(type, getCompatibleBufferedImageType(new BufferedImage(1, 1, type))); - } - } - - @Test - public void testGetCompatibleBufferedImageType() throws Exception { - for (int type = BufferedImage.TYPE_INT_RGB; type <= BufferedImage.TYPE_BYTE_INDEXED; type++) { // 1 - 13 - assertEquals(type, getCompatibleBufferedImageType(createCompatibleMappedImage(1, 1, type))); - } - } -} \ No newline at end of file diff --git a/sandbox/sandbox-common/src/test/java/com/twelvemonkeys/io/StringInputStreamTest.java b/sandbox/sandbox-common/src/test/java/com/twelvemonkeys/io/StringInputStreamTest.java deleted file mode 100644 index d515e8bd..00000000 --- a/sandbox/sandbox-common/src/test/java/com/twelvemonkeys/io/StringInputStreamTest.java +++ /dev/null @@ -1,126 +0,0 @@ -package com.twelvemonkeys.io; - -import org.junit.Test; - -import java.io.IOException; -import java.nio.charset.Charset; -import java.util.Arrays; - -import static org.junit.Assert.*; - -/** - * StringInputStreamTest - * - * @author Harald Kuhr - * @author last modified by $Author: haraldk$ - * @version $Id: StringInputStreamTest.java,v 1.0 03.09.13 10:40 haraldk Exp$ - */ -public class StringInputStreamTest { - - static final Charset UTF8 = Charset.forName("UTF-8"); - static final String LONG_STRING = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse id est lobortis, elementum nisi id, mollis urna. Morbi lorem nulla, vehicula ut ultricies ut, blandit sit amet metus. Praesent ut urna et arcu commodo tempus. Aenean dapibus commodo ligula, non vehicula leo dictum a. Aenean at leo ut eros hendrerit pellentesque. Phasellus sagittis arcu non faucibus faucibus. Sed volutpat vulputate metus sed consequat. Aenean auctor sapien sit amet erat dictum laoreet. Nullam libero felis, rutrum scelerisque elit eu, porta mollis nisi. Vestibulum vel ultricies turpis, vel dignissim arcu.\n" + - "Ut convallis erat et dapibus feugiat. Pellentesque eu dictum ligula, et interdum nibh. Sed rutrum justo a leo faucibus eleifend. Proin est justo, porttitor vel nulla egestas, faucibus scelerisque lacus. Vivamus sit amet gravida nibh. Praesent odio diam, ornare vitae mi nec, pretium ultrices tellus. Pellentesque vitae felis consequat mauris lacinia condimentum in ut nibh. In odio quam, laoreet luctus velit vel, suscipit mollis leo. Etiam justo nulla, posuere et massa non, pretium vehicula diam. Sed porta molestie mauris quis condimentum. Sed quis gravida ipsum, eget porttitor felis. Vivamus volutpat velit vitae dolor convallis, nec malesuada est porttitor. Proin sed purus vel leo pretium suscipit. Morbi ut nibh quis tortor vehicula porttitor non sit amet lorem. Proin tempor vel sem sit amet accumsan.\n" + - "Cras vulputate orci a lorem luctus, vel egestas leo porttitor. Duis venenatis odio et mauris molestie rutrum. Mauris gravida volutpat odio at consequat. Mauris eros purus, bibendum in vulputate vitae, laoreet quis libero. Quisque lacinia, neque sed semper fringilla, elit dolor sagittis est, nec tincidunt ipsum risus ut sem. Maecenas consectetur aliquam augue. Etiam neque mi, euismod eget metus quis, molestie lacinia odio. Sed eget sollicitudin metus. Phasellus facilisis augue et sem facilisis, consequat mollis augue ultricies.\n" + - "Vivamus in porta massa. Sed eget lorem non lectus viverra pretium. Curabitur convallis posuere est vestibulum vulputate. Maecenas placerat risus ut dui hendrerit, sed suscipit magna tincidunt. Etiam ut mattis dolor, quis dictum velit. Donec ut dui sit amet libero convallis euismod. Phasellus dapibus dolor in nibh volutpat, eu scelerisque neque tempus. Maecenas a rhoncus velit. Etiam sollicitudin, leo non euismod vehicula, lectus risus aliquet metus, quis cursus purus orci non turpis. Nulla vel enim tortor. Quisque nec mi vulputate, convallis orci vel, suscipit nibh. Sed sed tellus id elit commodo laoreet ut euismod ligula. Mauris suscipit commodo interdum. Phasellus scelerisque arcu nec nibh porta, et semper massa rutrum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.\n" + - "Praesent cursus, sapien ut venenatis malesuada, turpis nulla venenatis velit, nec tristique leo turpis auctor purus. Curabitur non porta urna. Sed vitae felis massa. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Phasellus scelerisque id dolor nec fermentum. Etiam suscipit tincidunt odio, sed molestie elit fringilla in. Phasellus nec euismod lacus. Suspendisse bibendum vulputate viverra. Fusce mollis pharetra imperdiet. Phasellus tortor eros, rhoncus volutpat diam in, scelerisque viverra felis. Ut ornare urna commodo, pretium mauris eget, eleifend ipsum."; - static final String SHORT_STRING = "Java"; - - @Test - public void testReadShortString() throws IOException { - StringInputStream stream = new StringInputStream(SHORT_STRING, UTF8); - - byte[] value = SHORT_STRING.getBytes(UTF8); - for (int i = 0; i < value.length; i++) { - int read = stream.read(); - assertEquals(String.format("Wrong value at offset %s: '%s' != '%s'", i, String.valueOf((char) value[i]), String.valueOf((char) (byte) read)), value[i] &0xff, read); - } - - assertEquals(-1, stream.read()); - } - - @Test - public void testReadSubString() throws IOException { - StringInputStream stream = new StringInputStream("foo bar xyzzy", 4, 3, UTF8); - - byte[] value = "bar".getBytes(UTF8); - for (int i = 0; i < value.length; i++) { - int read = stream.read(); - assertEquals(String.format("Wrong value at offset %s: '%s' != '%s'", i, String.valueOf((char) value[i]), String.valueOf((char) (byte) read)), value[i] &0xff, read); - } - - assertEquals(-1, stream.read()); - } - - @Test - public void testReadNonAsciiString() throws IOException { - String string = "\u00c6\u00d8\u00c5\u00e6\u00f8\u00e5\u00e1\u00e9\u00c0\u00c8\u00fc\u00dc\u00df"; - StringInputStream stream = new StringInputStream(string, UTF8); - - byte[] value = string.getBytes(UTF8); - for (int i = 0; i < value.length; i++) { - int read = stream.read(); - assertEquals(String.format("Wrong value at offset %s: '%s' != '%s'", i, String.valueOf((char) value[i]), String.valueOf((char) (byte) read)), value[i] &0xff, read); - } - - assertEquals(-1, stream.read()); - } - - @Test - public void testReadLongString() throws IOException { - StringInputStream stream = new StringInputStream(LONG_STRING, UTF8); - - byte[] value = LONG_STRING.getBytes(UTF8); - for (int i = 0; i < value.length; i++) { - int read = stream.read(); - assertEquals(String.format("Wrong value at offset %s: '%s' != '%s'", i, String.valueOf((char) value[i]), String.valueOf((char) (byte) read)), value[i] &0xff, read); - } - - assertEquals(-1, stream.read()); - } - - @Test - public void testReadArrayLongString() throws IOException { - StringInputStream stream = new StringInputStream(LONG_STRING, UTF8); - - byte[] value = LONG_STRING.getBytes(UTF8); - byte[] buffer = new byte[17]; - int count; - for (int i = 0; i < value.length; i += count) { - count = stream.read(buffer); - assertArrayEquals(String.format("Wrong value at offset %s", i), Arrays.copyOfRange(value, i, i + count), Arrays.copyOfRange(buffer, 0, count)); - } - - assertEquals(-1, stream.read()); - } - - @Test - public void testReadArraySkipLongString() throws IOException { - StringInputStream stream = new StringInputStream(LONG_STRING, UTF8); - - byte[] value = LONG_STRING.getBytes(UTF8); - byte[] buffer = new byte[17]; - int count; - for (int i = 0; i < value.length; i += count) { - if (i % 2 == 0) { - count = (int) stream.skip(buffer.length); - } - else { - count = stream.read(buffer); - assertArrayEquals(String.format("Wrong value at offset %s", i), Arrays.copyOfRange(value, i, i + count), Arrays.copyOfRange(buffer, 0, count)); - } - } - - assertEquals(-1, stream.read()); - } - - /*@Test - public */void testPerformance() throws IOException { - for (int i = 0; i < 100000; i++) { - StringInputStream stream = new StringInputStream(LONG_STRING, UTF8); - while(stream.read() != -1) { - stream.available(); - } - } - - } -} diff --git a/sandbox/sandbox-common/src/test/java/com/twelvemonkeys/io/enc/DeflateEncoderTestCase.java b/sandbox/sandbox-common/src/test/java/com/twelvemonkeys/io/enc/DeflateEncoderTestCase.java deleted file mode 100644 index d2e501ff..00000000 --- a/sandbox/sandbox-common/src/test/java/com/twelvemonkeys/io/enc/DeflateEncoderTestCase.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.twelvemonkeys.io.enc; - -/** - * DeflateEncoderTest - *

- * - * @author Harald Kuhr - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/test/java/com/twelvemonkeys/io/enc/DeflateDecoderTestCase.java#1 $ - */ -public class DeflateEncoderTestCase extends EncoderAbstractTestCase { - protected Encoder createEncoder() { - return new DeflateEncoder(); - } - - protected Decoder createCompatibleDecoder() { - return new InflateDecoder(); - } -} diff --git a/sandbox/sandbox-common/src/test/java/com/twelvemonkeys/io/enc/InflateDecoderTestCase.java b/sandbox/sandbox-common/src/test/java/com/twelvemonkeys/io/enc/InflateDecoderTestCase.java deleted file mode 100644 index 70a6ad08..00000000 --- a/sandbox/sandbox-common/src/test/java/com/twelvemonkeys/io/enc/InflateDecoderTestCase.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.twelvemonkeys.io.enc; - -/** - * InflateEncoderTest - *

- * - * @author Harald Kuhr - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/test/java/com/twelvemonkeys/io/enc/InflateDecoderTestCase.java#1 $ - */ -public class InflateDecoderTestCase extends DecoderAbstractTestCase { - public Decoder createDecoder() { - return new InflateDecoder(); - } - - public Encoder createCompatibleEncoder() { - return new DeflateEncoder(); - } -} diff --git a/sandbox/sandbox-common/src/test/java/com/twelvemonkeys/lang/DuckTypeTestCase.java b/sandbox/sandbox-common/src/test/java/com/twelvemonkeys/lang/DuckTypeTestCase.java deleted file mode 100755 index 303db743..00000000 --- a/sandbox/sandbox-common/src/test/java/com/twelvemonkeys/lang/DuckTypeTestCase.java +++ /dev/null @@ -1,246 +0,0 @@ -package com.twelvemonkeys.lang; - -import junit.framework.TestCase; -import junit.framework.AssertionFailedError; - -/** - * “If it walks like a duck, looks like a duck, quacks like a duck, it must be…” - *

- * - * @author Harald Kuhr - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-sandbox/src/test/java/com/twelvemonkeys/lang/DuckTypeTestCase.java#1 $ - */ -public class DuckTypeTestCase extends TestCase { - - static public interface Eatable { - } - - static public interface Vegetable extends Eatable { - } - - static public interface Meat extends Eatable { - } - - static public interface Animal { - void walk(); - boolean canEat(Eatable pFood); - void eat(Eatable pFood); - } - - static public interface Bird extends Animal { - void fly(); - } - - static public interface Duck extends Bird { - void quack(); - } - - static public class DuckLookALike { - private boolean mWalking; - private boolean mFlying; - private boolean mQuacking; - - public void walk() { - mWalking = true; - } - - public void fly() { - mFlying = true; - } - - public void quack() { - mQuacking = true; - } - - void reset() { - mWalking = mFlying = mQuacking = false; - } - - boolean verify() { - return mWalking && mFlying && mQuacking; - } - } - - static public class Swan extends DuckLookALike { - } - - static public class VeggieEater { - private boolean mHappy; - - public boolean canEat(Eatable pFood) { - return pFood instanceof Vegetable; - } - - public void eat(Eatable pFood) { - if (pFood == this) { - throw new IllegalArgumentException("CantEatMyselfException: duh"); - } - if (!canEat(pFood)) { - throw new NotVegetableException("yuck"); - } - - mHappy = true; - } - - void reset() { - mHappy = false; - } - - boolean verify() { - return mHappy; - } - } - - static class NotVegetableException extends RuntimeException { - public NotVegetableException(String message) { - super(message); - } - } - - public static void testTooManyThingsAtOnce() { - DuckLookALike lookALike = new DuckLookALike(); - VeggieEater veggieEater = new VeggieEater(); - - Object obj = DuckType.implement(new Class[]{Duck.class, Meat.class}, - new Object[]{lookALike, veggieEater}); - assertTrue(obj instanceof Duck); - assertTrue(obj instanceof Meat); - Duck duck = (Duck) obj; - - Bird another = (Bird) DuckType.implement(new Class[]{Duck.class, Meat.class}, - new Object[]{lookALike, veggieEater}); - - Duck uglyDuckling = (Duck) DuckType.implement(new Class[] {Duck.class, Meat.class}, - new Object[] {new Swan(), new VeggieEater()}); - - assertNotNull(duck.toString()); - - assertTrue("Duck is supposed to equal itself (identity crisis)", duck.equals(duck)); - - assertEquals("Duck is supposed to equal other duck with same stuffing", duck, another); - - assertFalse("Some ducks are more equal than others", duck.equals(uglyDuckling)); - - duck.walk(); - duck.quack(); - duck.quack(); - duck.fly(); - - assertTrue("Duck is supposed to quack", lookALike.verify()); - - Vegetable cabbage = new Vegetable() {}; - assertTrue("Duck is supposed to like cabbage", duck.canEat(cabbage)); - duck.eat(cabbage); - assertTrue("Duck is supposed to eat vegetables", veggieEater.verify()); - - veggieEater.reset(); - - Throwable exception = null; - try { - duck.eat((Meat) uglyDuckling); - fail("Duck ate distant cousin"); - } - catch (AssertionFailedError e) { - throw e; - } - catch (Throwable t) { - exception = t; - } - assertTrue("Incorrect quack: " + exception, exception instanceof NotVegetableException); - - - // TODO: There's a flaw in the design here.. - // The "this" keyword don't work well with proxies.. - - // Something that could possibly work, is: - // All proxy-aware delegates need a method getThis() / getSelf()... - // (using a field won't work for delegates that are part of multiple - // proxies). - // The default implementation should only return "this".. - // TBD: How do we know which proxy the current delegate is part of? - - exception = null; - try { - duck.eat((Meat) duck); - fail("Duck ate itself"); - } - catch (AssertionFailedError e) { - throw e; - } - catch (Throwable t) { - exception = t; - } - assertTrue("Duck tried to eat itself: " + exception, exception instanceof IllegalArgumentException); - } - - public void testExpandedArgs() { - Object walker = new Object() { - public void walk() { - } - }; - Object eater = new Object() { - // Assignable, but not direct match - public boolean canEat(Object pFood) { - return true; - } - - // Assignable, but not direct match - public void eat(Object pFood) { - } - }; - - Animal rat = (Animal) DuckType.implement(new Class[]{Animal.class, Meat.class}, - new Object[]{walker, eater}); - - assertNotNull(rat); - assertTrue(rat instanceof Meat); - - // Rats eat everything - Eatable smellyFood = new Eatable() {boolean tastesVeryBad = true;}; - assertTrue("Rat did not eat smelly food", rat.canEat(smellyFood)); - } - - public void testExpandedArgsFail() { - try { - Object walker = new Object() { - public void walk() { - } - }; - Object eater = new Object() { - // Not assignable return type - public int canEat(Eatable pFood) { - return 1; - } - - // Assignable, but not direct match - public void eat(Object pFood) { - } - }; - DuckType.implement(new Class[]{Animal.class}, - new Object[]{walker, eater}); - - fail("This kind of animal won't live long"); - } - catch (DuckType.NoMatchingMethodException e) { - } - } - - public void testStubAbstract() { - Object obj = DuckType.implement(new Class[]{Animal.class}, - new Object[]{new Object()}, true); - assertTrue(obj instanceof Animal); - Animal unicorn = (Animal) obj; - assertNotNull(unicorn); - - // Should create a meaningful string representation - assertNotNull(unicorn.toString()); - - // Unicorns don't fly, as they are only an abstract idea.. - try { - unicorn.walk(); - fail("Unicorns should not fly, as they are only an abstract idea"); - } - catch (AbstractMethodError e) { - } - } -} diff --git a/sandbox/sandbox-common/src/test/java/com/twelvemonkeys/lang/ExceptionUtilTest.java b/sandbox/sandbox-common/src/test/java/com/twelvemonkeys/lang/ExceptionUtilTest.java deleted file mode 100644 index 90b5aed5..00000000 --- a/sandbox/sandbox-common/src/test/java/com/twelvemonkeys/lang/ExceptionUtilTest.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2012, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.lang; - -import org.junit.Ignore; -import org.junit.Test; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.sql.SQLException; - -/** - * ExceptionUtilTest - * - * @author Harald Kuhr - * @author last modified by $Author: haraldk$ - * @version $Id: ExceptionUtilTest.java,v 1.0 11.04.12 16:07 haraldk Exp$ - */ -@Ignore("Under development") -public class ExceptionUtilTest { - @Test(expected = BadException.class) - @SuppressWarnings({"InfiniteLoopStatement"}) - public void test() { - while (true) { - foo(); - } - } - - @SuppressWarnings({"unchecked", "varargs"}) - private static void foo() { - try { - bar(); - } - catch (Throwable t) { - ExceptionUtil.handle(t, - new ExceptionUtil.ThrowableHandler(IOException.class) { - public void handle(final IOException pThrowable) { - System.out.println("IOException: " + pThrowable + " handled"); - } - }, - new ExceptionUtil.ThrowableHandler(SQLException.class, NumberFormatException.class) { - public void handle(final Exception pThrowable) { - System.out.println("Exception: " + pThrowable + " handled"); - } - } - ); - } - } - - private static void bar() { - baz(); - } - - @SuppressWarnings({"ThrowableInstanceNeverThrown"}) - private static void baz() { - double random = Math.random(); - if (random < (2.0 / 3.0)) { - ExceptionUtil.throwUnchecked(new FileNotFoundException("FNF Boo")); - } - if (random < (5.0 / 6.0)) { - ExceptionUtil.throwUnchecked(new SQLException("SQL Boo")); - } - else { - ExceptionUtil.throwUnchecked(new BadException("Some Boo")); - } - } - - static final class BadException extends Exception { - public BadException(String s) { - super(s); - } - } -} diff --git a/sandbox/sandbox-common/src/test/java/com/twelvemonkeys/util/MappedBeanFactoryTestCase.java b/sandbox/sandbox-common/src/test/java/com/twelvemonkeys/util/MappedBeanFactoryTestCase.java deleted file mode 100755 index bf313abd..00000000 --- a/sandbox/sandbox-common/src/test/java/com/twelvemonkeys/util/MappedBeanFactoryTestCase.java +++ /dev/null @@ -1,578 +0,0 @@ -/* - * Copyright (c) 2009, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.util; - -import com.twelvemonkeys.util.MappedBeanFactory; -import junit.framework.AssertionFailedError; -import static org.junit.Assert.*; -import static org.junit.Assert.assertEquals; -import org.junit.Test; - -import java.awt.*; -import java.awt.event.ActionListener; -import java.beans.IntrospectionException; -import java.beans.PropertyChangeListener; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.io.*; - -/** - * MappedBeanFactoryTestCase - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-sandbox/src/test/java/com/twelvemonkeys/sandbox/MappedBeanFactoryTestCase.java#1 $ - */ -public class MappedBeanFactoryTestCase { - - public static interface Foo { - boolean isFoo(); - - int getBar(); - void setBar(int bar); - - Rectangle getBounds(); - void setBounds(Rectangle bounds); - } - - public static interface DefaultFoo extends Foo { -// @MappedBeanFactory.DefaultBooleanValue - @MappedBeanFactory.DefaultValue(booleanValue = false) - boolean isFoo(); - - @MappedBeanFactory.DefaultIntValue - int getBar(); - void setBar(int bar); - - Rectangle getBounds(); - void setBounds(Rectangle bounds); - - @SuppressWarnings({"CloneDoesntDeclareCloneNotSupportedException"}) - DefaultFoo clone(); - } - - static interface ObservableFoo extends DefaultFoo { - @MappedBeanFactory.DefaultBooleanValue(true) - boolean isFoo(); - - @MappedBeanFactory.DefaultIntValue(1) - int getBar(); - - @MappedBeanFactory.NotNull - Rectangle getBounds(); - - @MappedBeanFactory.Observable - void setBounds(@MappedBeanFactory.NotNull Rectangle bounds); - - // TODO: This method should be implicitly supported, and throw IllegalArgument, if NoSuchProperty - // TODO: An observable interface to extend? - void addPropertyChangeListener(String property, PropertyChangeListener listener); - } - - @Test - public void testToString() { - Foo foo = MappedBeanFactory.as(DefaultFoo.class); - assertNotNull(foo); - assertNotNull(foo.toString()); - assertTrue(foo.toString().contains(DefaultFoo.class.getName())); - - // TODO: Consider this: -// assertTrue(foo.toString().contains("foo=false")); -// assertTrue(foo.toString().contains("bar=0")); -// assertTrue(foo.toString().contains("bounds=null")); - } - - @Test - public void testClone() { - DefaultFoo foo = MappedBeanFactory.as(DefaultFoo.class, Collections.singletonMap("foo", true)); - DefaultFoo clone = foo.clone(); - assertNotSame(foo, clone); - assertEquals(foo, clone); - assertEquals(foo.hashCode(), clone.hashCode()); - assertEquals(foo.isFoo(), clone.isFoo()); - } - - @Test - public void testSerializable() throws IOException, ClassNotFoundException { - Foo foo = MappedBeanFactory.as(DefaultFoo.class, Collections.singletonMap("foo", true)); - - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - ObjectOutputStream outputStream = new ObjectOutputStream(bytes); - outputStream.writeObject(foo); - - ObjectInputStream inputStream = new ObjectInputStream(new ByteArrayInputStream(bytes.toByteArray())); - Foo bar = (Foo) inputStream.readObject(); - - assertNotSame(foo, bar); - assertEquals(foo, bar); - assertEquals(foo.hashCode(), bar.hashCode()); - assertEquals(foo.isFoo(), bar.isFoo()); - } - - @Test - public void testNotEqualsNull() { - Foo foo = MappedBeanFactory.as(DefaultFoo.class); - - @SuppressWarnings({"ObjectEqualsNull"}) - boolean equalsNull = foo.equals(null); - - assertFalse(equalsNull); - } - - @Test - public void testEqualsSelf() { - Foo foo = MappedBeanFactory.as(DefaultFoo.class, new HashMap() { - @SuppressWarnings({"EqualsWhichDoesntCheckParameterClass"}) - @Override - public boolean equals(Object o) { - throw new AssertionFailedError("Don't need to test map for equals if same object"); - } - }); - - assertTrue(foo.equals(foo)); - } - - @Test - public void testEqualsOther() { - Foo foo = MappedBeanFactory.as(DefaultFoo.class); - Foo other = MappedBeanFactory.as(DefaultFoo.class); - - assertEquals(foo, other); - } - - @Test - public void testEqualsOtherModifiedSameValue() { - Foo foo = MappedBeanFactory.as(DefaultFoo.class, new HashMap()); - Foo other = MappedBeanFactory.as(DefaultFoo.class, new HashMap(Collections.singletonMap("bar", 0))); - - assertEquals(foo, other); - - // No real change - other.setBar(foo.getBar()); - assertTrue(foo.equals(other)); - } - - @Test - public void testNotEqualsOtherModified() { - Foo foo = MappedBeanFactory.as(DefaultFoo.class); - Foo other = MappedBeanFactory.as(DefaultFoo.class); - - assertEquals(foo, other); - - // Real change - other.setBar(42); - assertFalse(foo.equals(other)); - } - - @Test - public void testEqualsSubclass() { - Foo foo = MappedBeanFactory.as(DefaultFoo.class); - - Foo sub = MappedBeanFactory.as(ObservableFoo.class); - assertEquals(foo, sub); - } - - @Test - public void testNotEqualsDifferentValues() { - Foo foo = MappedBeanFactory.as(DefaultFoo.class); - Foo bar = MappedBeanFactory.as(DefaultFoo.class, Collections.singletonMap("bar", true)); - assertFalse(foo.equals(bar)); - } - - @Test - public void testNotEqualsDifferentClass() { - Foo foo = MappedBeanFactory.as(DefaultFoo.class); - ActionListener actionListener = MappedBeanFactory.as(ActionListener.class); - assertFalse(foo.equals(actionListener)); - } - - @Test - public void testBooleanReadOnly() { - Foo foo = MappedBeanFactory.as(DefaultFoo.class, Collections.singletonMap("foo", true)); - - assertNotNull(foo); - assertEquals(true, foo.isFoo()); - } - - @Test - public void testBooleanEmpty() { - Foo foo = MappedBeanFactory.as(DefaultFoo.class, new HashMap()); - - assertNotNull(foo); - - try { - foo.isFoo(); - fail("Expected NullPointerException"); - } - catch (NullPointerException expected) { - } - } - - @Test - public void testBooleanEmptyWithConverter() { - Foo foo = MappedBeanFactory.as(DefaultFoo.class, new HashMap(), new NullBooleanConverter(true)); - - assertNotNull(foo); - - assertEquals(true, foo.isFoo()); - } - - @Test - public void testIntReadOnly() { - Foo foo = MappedBeanFactory.as(DefaultFoo.class, Collections.singletonMap("bar", 1)); - - assertNotNull(foo); - assertEquals(1, foo.getBar()); - - try { - foo.setBar(42); - fail("Expected UnsupportedOperationException"); - } - catch (UnsupportedOperationException expected) { - } - } - - @Test - public void testIntReadWrite() { - Foo foo = MappedBeanFactory.as(DefaultFoo.class, new HashMap(Collections.singletonMap("bar", 1))); - - assertNotNull(foo); - assertEquals(1, foo.getBar()); - - foo.setBar(42); - assertEquals(42, foo.getBar()); - } - - @Test - public void testIntNull() { - Foo foo = MappedBeanFactory.as(DefaultFoo.class, new HashMap(Collections.singletonMap("bar", null))); - - assertNotNull(foo); - - // TODO: Handle null-values smarter, maybe throw a better exception? - // TODO: Consider allowing custom initializers? - try { - foo.getBar(); - fail("Expected NullPointerException"); - } - catch (NullPointerException expected) { - } - - foo.setBar(42); - assertEquals(42, foo.getBar()); - } - - @Test - public void testIntNullWithConverter() { - Foo foo = MappedBeanFactory.as(DefaultFoo.class, new HashMap(Collections.singletonMap("bar", null)), new NullIntConverter(1)); - - assertNotNull(foo); - - assertEquals(1, foo.getBar()); - - foo.setBar(42); - assertEquals(42, foo.getBar()); - } - - @Test - public void testIntWrongType() { - Foo foo = MappedBeanFactory.as(DefaultFoo.class, new HashMap(Collections.singletonMap("bar", "1"))); - - assertNotNull(foo); - - // TODO: Handle conversion smarter, maybe throw a better exception? - try { - foo.getBar(); - fail("Expected ClassCastException"); - } - catch (ClassCastException expected) { - } - - // TODO: Should we allow changing type? - try { - foo.setBar(42); - fail("Expected ClassCastException"); - } - catch (ClassCastException expected) { - } - } - - @Test - public void testBounds() { - Rectangle rectangle = new Rectangle(2, 2, 4, 4); - Foo foo = MappedBeanFactory.as(DefaultFoo.class, new HashMap(Collections.singletonMap("bounds", rectangle))); - - assertNotNull(foo); - assertEquals(rectangle, foo.getBounds()); - - foo.setBounds(new Rectangle()); - assertEquals(new Rectangle(), foo.getBounds()); - } - - @Test - public void testBoundsNull() { - Foo foo = MappedBeanFactory.as(DefaultFoo.class, new HashMap(Collections.singletonMap("bounds", null))); - - assertNotNull(foo); - assertNull(foo.getBounds()); - - Rectangle rectangle = new Rectangle(2, 2, 4, 4); - foo.setBounds(rectangle); - assertEquals(rectangle, foo.getBounds()); - - foo.setBounds(null); - assertEquals(null, foo.getBounds()); - } - - @Test - public void testBoundsNullWithConverter() { - // TODO: Allow @NotNull annotations, to say that null is not a valid return value/paramter? - Foo foo = MappedBeanFactory.as(ObservableFoo.class, new HashMap(Collections.singletonMap("bounds", null)), new MappedBeanFactory.Converter() { - public Class getFromType() { - return Void.class; - } - - public Class getToType() { - return Rectangle.class; - } - - public Rectangle convert(Void value, Rectangle old) { - return new Rectangle(10, 10, 10, 10); - } - }); - - assertNotNull(foo); - // TODO: The current problem is that null is okay as return value, even if not specified for interface... - assertEquals(new Rectangle(10, 10, 10, 10), foo.getBounds()); - - Rectangle rectangle = new Rectangle(2, 2, 4, 4); - foo.setBounds(rectangle); - assertEquals(rectangle, foo.getBounds()); - } - - @Test - public void testBoundsAsMapWithConverter() throws IntrospectionException { - Rectangle rectangle = new Rectangle(2, 2, 4, 4); - Map recAsMap = new HashMap(); - recAsMap.put("x", 2); - recAsMap.put("y", 2); - recAsMap.put("width", 4); - recAsMap.put("height", 4); - - HashMap map = new HashMap(Collections.singletonMap("bounds", recAsMap)); - - // TODO: Allow for registering superclasses/interfaces like Map... - Foo foo = MappedBeanFactory.as(DefaultFoo.class, map, new MapRectangleConverter(), new RectangleMapConverter()); - - assertNotNull(foo); - - assertEquals(rectangle, foo.getBounds()); - - foo.setBounds(new Rectangle()); - assertEquals(new Rectangle(), foo.getBounds()); - assertEquals(recAsMap, map.get("bounds")); - assertSame(recAsMap, map.get("bounds")); - - // TODO: The converter should maybe not have to handle this - foo.setBounds(null); - assertNull(foo.getBounds()); - assertEquals(recAsMap, map.get("bounds")); - assertSame(recAsMap, map.get("bounds")); - - Rectangle bounds = new Rectangle(1, 1, 1, 1); - foo.setBounds(bounds); - assertEquals(bounds, foo.getBounds()); - assertEquals(1, foo.getBounds().x); - assertEquals(1, foo.getBounds().y); - assertEquals(1, foo.getBounds().width); - assertEquals(1, foo.getBounds().height); - assertEquals(recAsMap, map.get("bounds")); - assertSame(recAsMap, map.get("bounds")); - } - - @Test - public void testSpeed() { - // How many times faster may the direct access be, before we declare failure? - final int threshold = 50; - - Foo foo = MappedBeanFactory.as(DefaultFoo.class, new HashMap(Collections.singletonMap("foo", false))); - - Foo bar = new Foo() { - public boolean isFoo() { - return false; - } - - public int getBar() { - throw new UnsupportedOperationException("Method getBar not implemented"); - } - - public void setBar(int bar) { - throw new UnsupportedOperationException("Method setBar not implemented"); - } - - public Rectangle getBounds() { - throw new UnsupportedOperationException("Method getBounds not implemented"); // TODO: Implement - } - - public void setBounds(Rectangle bounds) { - throw new UnsupportedOperationException("Method setBounds not implemented"); // TODO: Implement - } - }; - - final int warmup = 50005; - final int iter = 2000000; - for (int i = 0; i < warmup; i++) { - if (foo.isFoo()) { - fail(); - } - if (bar.isFoo()) { - fail(); - } - } - - long startProxy = System.nanoTime(); - for (int i = 0; i < iter; i++) { - if (foo.isFoo()) { - fail(); - } - } - long proxyTime = System.nanoTime() - startProxy; - - long startJava = System.nanoTime(); - for (int i = 0; i < iter; i++) { - if (bar.isFoo()) { - fail(); - } - } - long javaTime = System.nanoTime() - startJava; - - assertTrue( - String.format( - "Proxy time (%1$,d ms) greater than %3$d times direct invocation (%2$,d ms)", - proxyTime / 1000, javaTime / 1000, threshold - ), - proxyTime < threshold * javaTime); - } - - private static class MapRectangleConverter implements MappedBeanFactory.Converter { - public Class getFromType() { - return HashMap.class; - } - - public Class getToType() { - return Rectangle.class; - } - - public Rectangle convert(final HashMap pMap, Rectangle pOldValue) { - if (pMap == null || pMap.isEmpty()) { - return null; - } - - Rectangle rectangle = pOldValue != null ? pOldValue : new Rectangle(); - - rectangle.x = (Integer) pMap.get("x"); - rectangle.y = (Integer) pMap.get("y"); - rectangle.width = (Integer) pMap.get("width"); - rectangle.height = (Integer) pMap.get("height"); - - return rectangle; - } - } - - private static class RectangleMapConverter implements MappedBeanFactory.Converter { - public Class getToType() { - return HashMap.class; - } - - public Class getFromType() { - return Rectangle.class; - } - - public HashMap convert(final Rectangle pRectangle, HashMap pOldValue) { - @SuppressWarnings("unchecked") - HashMap map = pOldValue != null ? pOldValue : new HashMap(); - - if (pRectangle != null) { - map.put("x", pRectangle.x); - map.put("y", pRectangle.y); - map.put("width", pRectangle.width); - map.put("height", pRectangle.height); - } - else { - map.remove("x"); - map.remove("y"); - map.remove("width"); - map.remove("height"); - } - - return map; - } - } - - private static class NullIntConverter implements MappedBeanFactory.Converter { - private Integer mInitialValue; - - public NullIntConverter(int pValue) { - mInitialValue = pValue; - } - - public Class getFromType() { - return Void.class; - } - - public Class getToType() { - return Integer.class; - } - - public Integer convert(Void value, Integer old) { - return mInitialValue; - } - } - - private static class NullBooleanConverter implements MappedBeanFactory.Converter { - private Boolean mInitialValue; - - public NullBooleanConverter(boolean pValue) { - mInitialValue = pValue; - } - - public Class getFromType() { - return Void.class; - } - - public Class getToType() { - return Boolean.class; - } - - public Boolean convert(Void value, Boolean old) { - return mInitialValue; - } - } -} diff --git a/sandbox/sandbox-common/src/test/java/com/twelvemonkeys/util/UUIDFactoryTest.java b/sandbox/sandbox-common/src/test/java/com/twelvemonkeys/util/UUIDFactoryTest.java deleted file mode 100644 index 10397d13..00000000 --- a/sandbox/sandbox-common/src/test/java/com/twelvemonkeys/util/UUIDFactoryTest.java +++ /dev/null @@ -1,419 +0,0 @@ -package com.twelvemonkeys.util; - -import org.junit.Ignore; -import org.junit.Test; - -import java.io.UnsupportedEncodingException; -import java.math.BigInteger; -import java.util.Arrays; -import java.util.Comparator; -import java.util.Random; -import java.util.UUID; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; - -import static org.junit.Assert.*; - -public class UUIDFactoryTest { - private static final String EXAMPLE_COM_UUID = "http://www.example.com/uuid/"; - - // Nil UUID - - @Test - public void testNilUUIDVariant() { - assertEquals(0, UUIDFactory.NIL.variant()); - } - @Test - public void testNilUUIDVersion() { - assertEquals(0, UUIDFactory.NIL.version()); - } - - @Test - public void testNilUUIDFromStringRep() { - assertEquals(UUID.fromString("00000000-0000-0000-0000-000000000000"), UUIDFactory.NIL); - } - - @Test - public void testNilUUIDFromLong() { - assertEquals(new UUID(0l, 0l), UUIDFactory.NIL); - } - - // Version 3 UUIDs (for comparison with v5) - - @Test - public void testVersion3NameBasedMD5Variant() throws UnsupportedEncodingException { - assertEquals(2, UUID.nameUUIDFromBytes(EXAMPLE_COM_UUID.getBytes("UTF-8")).variant()); - } - @Test - public void testVersion3NameBasedMD5Version() throws UnsupportedEncodingException { - assertEquals(3, UUID.nameUUIDFromBytes(EXAMPLE_COM_UUID.getBytes("UTF-8")).version()); - } - - @Test - public void testVersion3NameBasedMD5Equals() throws UnsupportedEncodingException { - UUID a = UUID.nameUUIDFromBytes(EXAMPLE_COM_UUID.getBytes("UTF-8")); - UUID b = UUID.nameUUIDFromBytes(EXAMPLE_COM_UUID.getBytes("UTF-8")); - assertEquals(a, b); - } - - @Test - public void testVersion3NameBasedMD5NotEqualSHA1() throws UnsupportedEncodingException { - UUID a = UUID.nameUUIDFromBytes(EXAMPLE_COM_UUID.getBytes("UTF-8")); - UUID b = UUIDFactory.nameUUIDv5FromBytes(EXAMPLE_COM_UUID.getBytes("UTF-8")); - assertFalse(a.equals(b)); - } - - @Test - public void testVersion3NameBasedMD5FromStringRep() throws UnsupportedEncodingException { - UUID a = UUID.nameUUIDFromBytes(EXAMPLE_COM_UUID.getBytes("UTF-8")); - assertEquals(a, UUID.fromString(a.toString())); - } - - // Version 5 UUIDs - - @Test - public void testVersion5NameBasedSHA1Variant() throws UnsupportedEncodingException { - UUID a = UUIDFactory.nameUUIDv5FromBytes(EXAMPLE_COM_UUID.getBytes("UTF-8")); - assertEquals(2, a.variant()); - } - @Test - public void testVersion5NameBasedSHA1Version() throws UnsupportedEncodingException { - UUID a = UUIDFactory.nameUUIDv5FromBytes(EXAMPLE_COM_UUID.getBytes("UTF-8")); - assertEquals(5, a.version()); - } - - @Test - public void testVersion5NameBasedSHA1Equals() throws UnsupportedEncodingException { - UUID a = UUIDFactory.nameUUIDv5FromBytes(EXAMPLE_COM_UUID.getBytes("UTF-8")); - UUID b = UUIDFactory.nameUUIDv5FromBytes(EXAMPLE_COM_UUID.getBytes("UTF-8")); - assertEquals(a, b); - } - - @Test - public void testVersion5NameBasedSHA1Different() throws UnsupportedEncodingException { - Random random = new Random(); - byte[] data = new byte[128]; - random.nextBytes(data); - - UUID a = UUIDFactory.nameUUIDv5FromBytes(data); - - // Swap a random byte with its "opposite" - int i; - while (data[i = random.nextInt(data.length)] == data[data.length - 1 - i]) {} - data[i] = data[data.length - 1 - i]; - - UUID b = UUIDFactory.nameUUIDv5FromBytes(data); - - assertFalse(a.equals(b)); - } - - @Test - public void testVersion5NameBasedSHA1NotEqualMD5() throws UnsupportedEncodingException { - UUID a = UUIDFactory.nameUUIDv5FromBytes(EXAMPLE_COM_UUID.getBytes("UTF-8")); - UUID b = UUID.nameUUIDFromBytes(EXAMPLE_COM_UUID.getBytes("UTF-8")); - assertFalse(a.equals(b)); - } - - @Test - public void testVersion5NameBasedSHA1FromStringRep() throws UnsupportedEncodingException { - UUID a = UUIDFactory.nameUUIDv5FromBytes(EXAMPLE_COM_UUID.getBytes("UTF-8")); - assertEquals(a, UUID.fromString(a.toString())); - } - - // Version 1 UUIDs - - @Test - public void testVersion1NodeBasedVariant() { - assertEquals(2, UUIDFactory.timeNodeBasedUUID().variant()); - } - - @Test - public void testVersion1NodeBasedVersion() { - assertEquals(1, UUIDFactory.timeNodeBasedUUID().version()); - } - - @Test - public void testVersion1NodeBasedFromStringRep() { - UUID uuid = UUIDFactory.timeNodeBasedUUID(); - assertEquals(uuid, UUID.fromString(uuid.toString())); - } - - @Test - public void testVersion1NodeBasedMacAddress() { - UUID uuid = UUIDFactory.timeNodeBasedUUID(); - assertEquals(UUIDFactory.MAC_ADDRESS_NODE, uuid.node()); - // TODO: Test that this is actually a Mac address from the local computer, or specified through system property? - } - - @Test - public void testVersion1NodeBasedClockSeq() { - UUID uuid = UUIDFactory.timeNodeBasedUUID(); - assertEquals(UUIDFactory.Clock.getClockSequence(), uuid.clockSequence()); - - // Test time fields (within reasonable limits +/- 100 ms or so?) - assertEquals(UUIDFactory.Clock.currentTimeHundredNanos(), uuid.timestamp(), 1e6); - } - - @Test - public void testVersion1NodeBasedTimestamp() { - UUID uuid = UUIDFactory.timeNodeBasedUUID(); - // Test time fields (within reasonable limits +/- 100 ms or so?) - assertEquals(UUIDFactory.Clock.currentTimeHundredNanos(), uuid.timestamp(), 1e6); - } - - @Test - public void testVersion1NodeBasedUniMulticastBitUnset() { - // Do it a couple of times, to avoid accidentally have correct bit - for (int i = 0; i < 100; i++) { - UUID uuid = UUIDFactory.timeNodeBasedUUID(); - assertEquals(0, (uuid.node() >> 40) & 1); - } - } - - @Test - public void testVersion1NodeBasedUnique() { - for (int i = 0; i < 100; i++) { - UUID a = UUIDFactory.timeNodeBasedUUID(); - UUID b = UUIDFactory.timeNodeBasedUUID(); - assertFalse(a.equals(b)); - } - } - - @Test - public void testVersion1SecureRandomVariant() { - assertEquals(2, UUIDFactory.timeRandomBasedUUID().variant()); - } - - @Test - public void testVersion1SecureRandomVersion() { - assertEquals(1, UUIDFactory.timeRandomBasedUUID().version()); - } - - @Test - public void testVersion1SecureRandomFromStringRep() { - UUID uuid = UUIDFactory.timeRandomBasedUUID(); - assertEquals(uuid, UUID.fromString(uuid.toString())); - } - - @Test - public void testVersion1SecureRandomNode() { - UUID uuid = UUIDFactory.timeRandomBasedUUID(); - assertEquals(UUIDFactory.SECURE_RANDOM_NODE, uuid.node()); - } - - @Test - public void testVersion1SecureRandomClockSeq() { - UUID uuid = UUIDFactory.timeRandomBasedUUID(); - assertEquals(UUIDFactory.Clock.getClockSequence(), uuid.clockSequence()); - } - - @Test - public void testVersion1SecureRandomTimestamp() { - UUID uuid = UUIDFactory.timeRandomBasedUUID(); - - // Test time fields (within reasonable limits +/- 100 ms or so?) - assertEquals(UUIDFactory.Clock.currentTimeHundredNanos(), uuid.timestamp(), 1e6); - } - - @Test - public void testVersion1SecureRandomUniMulticastBit() { - // Do it a couple of times, to avoid accidentally have correct bit - for (int i = 0; i < 100; i++) { - UUID uuid = UUIDFactory.timeRandomBasedUUID(); - assertEquals(1, (uuid.node() >> 40) & 1); - } - } - - @Test - public void testVersion1SecureRandomUnique() { - for (int i = 0; i < 100; i++) { - UUID a = UUIDFactory.timeRandomBasedUUID(); - UUID b = UUIDFactory.timeRandomBasedUUID(); - assertFalse(a.equals(b)); - } - } - - // Clock tests - - @Test(timeout = 10000l) - public void testClock() throws InterruptedException { - final long[] times = new long[100000]; - - ExecutorService service = Executors.newFixedThreadPool(20); - for (int i = 0; i < times.length; i++) { - final int index = i; - - service.submit(new Runnable() { - public void run() { - times[index] = UUIDFactory.Clock.currentTimeHundredNanos(); - } - }); - } - - service.shutdown(); - assertTrue("Execution timed out", service.awaitTermination(10, TimeUnit.SECONDS)); - - Arrays.sort(times); // This is what really takes time... - - for (int i = 0, timesLength = times.length; i < timesLength; i++) { - if (i == 0) { - continue; - } - - assertFalse(String.format("times[%d] == times[%d]: 0x%016x", i - 1, i, times[i]), times[i - 1] == times[i]); - } - } - - @Test(timeout = 10000l) - public void testClockSkew() throws InterruptedException { - long clockSequence = UUIDFactory.Clock.getClockSequence(); - - ExecutorService service = Executors.newFixedThreadPool(10); - for (int i = 0; i < 100000; i++) { - service.submit(new Runnable() { - public void run() { - UUIDFactory.Clock.currentTimeHundredNanos(); - } - }); - } - - service.shutdown(); - assertTrue("Execution timed out", service.awaitTermination(10, TimeUnit.SECONDS)); - - assertEquals(clockSequence, UUIDFactory.Clock.getClockSequence(), 1); // Verify that clock skew doesn't happen "often" - } - - // Tests for node address system property - - @Test - public void testParseNodeAddressesSingle() { - long[] nodes = UUIDFactory.parseMacAddressNodes("00:11:22:33:44:55"); - - assertEquals(1, nodes.length); - assertEquals(0x001122334455l, nodes[0]); - } - - @Test - public void testParseNodeAddressesSingleWhitespace() { - long[] nodes = UUIDFactory.parseMacAddressNodes(" 00:11:22:33:44:55\r\n"); - - assertEquals(1, nodes.length); - assertEquals(0x001122334455l, nodes[0]); - } - - @Test - public void testParseNodeAddressesMulti() { - long[] nodes = UUIDFactory.parseMacAddressNodes("00:11:22:33:44:55, aa:bb:cc:dd:ee:ff, \n\t 0a-1b-2c-3d-4e-5f,"); - - assertEquals(3, nodes.length); - assertEquals(0x001122334455l, nodes[0]); - assertEquals(0xaabbccddeeffl, nodes[1]); - assertEquals(0x0a1b2c3d4e5fl, nodes[2]); - } - - @Test(expected = NullPointerException.class) - public void testParseNodeAddressesNull() { - UUIDFactory.parseMacAddressNodes(null); - } - - @Test(expected = NumberFormatException.class) - public void testParseNodeAddressesEmpty() { - UUIDFactory.parseMacAddressNodes(""); - } - - @Test(expected = NumberFormatException.class) - public void testParseNodeAddressesNonAddress() { - UUIDFactory.parseMacAddressNodes("127.0.0.1"); - } - - @Test(expected = NumberFormatException.class) - public void testParseNodeAddressesBadAddress() { - UUIDFactory.parseMacAddressNodes("00a:11:22:33:44:55"); - } - - @Test(expected = NumberFormatException.class) - public void testParseNodeAddressesBadAddress4() { - UUIDFactory.parseMacAddressNodes("00:11:22:33:44:550"); - } - - @Test(expected = NumberFormatException.class) - public void testParseNodeAddressesBadAddress2() { - UUIDFactory.parseMacAddressNodes("0x:11:22:33:44:55"); - } - - @Test(expected = NumberFormatException.class) - public void testParseNodeAddressesBadAddress3() { - UUIDFactory.parseMacAddressNodes("00:11:22:33:44:55:99"); - } - - // Comparator test - - @Test - public void testComparator() { - UUID min = new UUID(0, 0); - // Long.MAX_VALUE and MIN_VALUE are really adjacent values when comparing unsigned... - UUID midLow = new UUID(Long.MAX_VALUE, Long.MAX_VALUE); - UUID midHigh = new UUID(Long.MIN_VALUE, Long.MIN_VALUE); - UUID max = new UUID(-1l, -1l); - - Comparator comparator = UUIDFactory.comparator(); - - assertEquals(0, comparator.compare(min, min)); - assertEquals(-1, comparator.compare(min, midLow)); - assertEquals(-1, comparator.compare(min, midHigh)); - assertEquals(-1, comparator.compare(min, max)); - - assertEquals(1, comparator.compare(midLow, min)); - assertEquals(0, comparator.compare(midLow, midLow)); - assertEquals(-1, comparator.compare(midLow, midHigh)); - assertEquals(-1, comparator.compare(midLow, max)); - - assertEquals(1, comparator.compare(midHigh, min)); - assertEquals(1, comparator.compare(midHigh, midLow)); - assertEquals(0, comparator.compare(midHigh, midHigh)); - assertEquals(-1, comparator.compare(midHigh, max)); - - assertEquals(1, comparator.compare(max, min)); - assertEquals(1, comparator.compare(max, midLow)); - assertEquals(1, comparator.compare(max, midHigh)); - assertEquals(0, comparator.compare(max, max)); - } - - @Test - public void testComparatorRandom() { - final Comparator comparator = UUIDFactory.comparator(); - - for (int i = 0; i < 10000; i++) { - UUID one = UUID.randomUUID(); - UUID two = UUID.randomUUID(); - - if (one.getMostSignificantBits() < 0 && two.getMostSignificantBits() >= 0 - || one.getMostSignificantBits() >= 0 && two.getMostSignificantBits() < 0 - || one.getLeastSignificantBits() < 0 && two.getLeastSignificantBits() >= 0 - || one.getLeastSignificantBits() >= 0 && two.getLeastSignificantBits() < 0) { - // These will differ due to the differing signs - assertEquals(-one.compareTo(two), comparator.compare(one, two)); - } - else { - assertEquals(one.compareTo(two), comparator.compare(one, two)); - } - } - } - - // Various testing - - @Ignore("Development testing only") - @Test - public void testOracleSYS_GUID() { - // TODO: Consider including this as a "fromCompactString" or similar... - String str = "AEB87F28E222D08AE043803BD559D08A"; - BigInteger bigInteger = new BigInteger(str, 16); // ALT: Create byte array of every 2 chars. - long msb = bigInteger.shiftRight(64).longValue(); - long lsb = bigInteger.longValue(); - UUID uuid = new UUID(msb, lsb); - System.err.println("uuid: " + uuid); - System.err.println("uuid.variant(): " + uuid.variant()); - System.err.println("uuid.version(): " + uuid.version()); - } -} \ No newline at end of file diff --git a/sandbox/sandbox-common/src/test/java/com/twlevemonkeys/image/MappedFileBufferTest.java b/sandbox/sandbox-common/src/test/java/com/twlevemonkeys/image/MappedFileBufferTest.java deleted file mode 100644 index 776a69d4..00000000 --- a/sandbox/sandbox-common/src/test/java/com/twlevemonkeys/image/MappedFileBufferTest.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2012, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twlevemonkeys.image; - -import com.twelvemonkeys.image.MappedFileBuffer; -import org.junit.Test; - -import java.awt.image.DataBuffer; -import java.io.IOException; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -/** - * MappedFileBufferTest - * - * @author Harald Kuhr - * @author last modified by $Author: haraldk$ - * @version $Id: MappedFileBufferTest.java,v 1.0 01.06.12 14:23 haraldk Exp$ - */ -public class MappedFileBufferTest { - @Test(expected = IllegalArgumentException.class) - public void testCreateInvalidType() throws IOException { - MappedFileBuffer.create(-1, 1, 1); - } - - @Test(expected = IllegalArgumentException.class) - public void testCreateInvalidSize() throws IOException { - MappedFileBuffer.create(DataBuffer.TYPE_USHORT, -1, 1); - } - - @Test(expected = IllegalArgumentException.class) - public void testCreateInvalidBands() throws IOException { - MappedFileBuffer.create(DataBuffer.TYPE_BYTE, 1, -1); - } - - @Test - public void testCreateByte() throws IOException { - DataBuffer buffer = MappedFileBuffer.create(DataBuffer.TYPE_BYTE, 256, 3); - assertNotNull(buffer); - - assertEquals(DataBuffer.TYPE_BYTE, buffer.getDataType()); - assertEquals(256, buffer.getSize()); - assertEquals(3, buffer.getNumBanks()); - } - - @Test - public void testSetGetElemByte() throws IOException { - final int size = 256; - DataBuffer buffer = MappedFileBuffer.create(DataBuffer.TYPE_BYTE, size, 3); - assertNotNull(buffer); - - for (int b = 0; b < 3; b++) { - for (int i = 0; i < size; i++) { - buffer.setElem(b, i, i); - - assertEquals(i, buffer.getElem(b, i)); - } - } - } - - @Test - public void testCreateUShort() throws IOException { - DataBuffer buffer = MappedFileBuffer.create(DataBuffer.TYPE_USHORT, 256, 3); - assertNotNull(buffer); - - assertEquals(DataBuffer.TYPE_USHORT, buffer.getDataType()); - assertEquals(256, buffer.getSize()); - assertEquals(3, buffer.getNumBanks()); - } - - @Test - public void testSetGetElemUShort() throws IOException { - final int size = (Short.MAX_VALUE + 1) * 2; - DataBuffer buffer = MappedFileBuffer.create(DataBuffer.TYPE_USHORT, size, 3); - assertNotNull(buffer); - - for (int b = 0; b < 3; b++) { - for (int i = 0; i < size; i++) { - buffer.setElem(b, i, i); - - assertEquals(i, buffer.getElem(b, i)); - } - } - } - - @Test - public void testCreateInt() throws IOException { - DataBuffer buffer = MappedFileBuffer.create(DataBuffer.TYPE_INT, 256, 3); - assertNotNull(buffer); - - assertEquals(DataBuffer.TYPE_INT, buffer.getDataType()); - assertEquals(256, buffer.getSize()); - assertEquals(3, buffer.getNumBanks()); - } - - @Test - public void testSetGetElemInt() throws IOException { - final int size = (Short.MAX_VALUE + 1) * 2; - DataBuffer buffer = MappedFileBuffer.create(DataBuffer.TYPE_INT, size, 3); - assertNotNull(buffer); - - for (int b = 0; b < 3; b++) { - for (int i = 0; i < size; i++) { - buffer.setElem(b, i, i * i); - - assertEquals(i * i, buffer.getElem(b, i)); - } - } - } -} diff --git a/sandbox/sandbox-imageio/pom.xml b/sandbox/sandbox-imageio/pom.xml deleted file mode 100644 index 0d831a2f..00000000 --- a/sandbox/sandbox-imageio/pom.xml +++ /dev/null @@ -1,86 +0,0 @@ - - - - - 4.0.0 - - com.twelvemonkeys.sandbox - sandbox - 3.1-SNAPSHOT - - sandbox-imageio - jar - TwelveMonkeys :: Sandbox :: ImageIO - - The TwelveMonkeys ImageIO Sandbox. New experimental stuff. Old retired stuff. - - - - - com.twelvemonkeys.common - common-io - compile - - - - com.twelvemonkeys.common - common-image - compile - - - - com.twelvemonkeys.imageio - imageio-core - compile - - - - com.twelvemonkeys.sandbox - sandbox-common - compile - - - - com.twelvemonkeys.common - common-io - test - test-jar - - - - com.twelvemonkeys.common - common-lang - test - test-jar - - - - diff --git a/sandbox/sandbox-imageio/src/main/java/com/twelvemonkeys/imageio/stream/Base64DataURLImageInputStreamSpi.java b/sandbox/sandbox-imageio/src/main/java/com/twelvemonkeys/imageio/stream/Base64DataURLImageInputStreamSpi.java deleted file mode 100644 index eab14369..00000000 --- a/sandbox/sandbox-imageio/src/main/java/com/twelvemonkeys/imageio/stream/Base64DataURLImageInputStreamSpi.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.twelvemonkeys.imageio.stream; - -import com.twelvemonkeys.io.StringInputStream; -import com.twelvemonkeys.io.enc.Base64Decoder; -import com.twelvemonkeys.io.enc.DecoderStream; - -import javax.imageio.spi.ImageInputStreamSpi; -import javax.imageio.stream.FileCacheImageInputStream; -import javax.imageio.stream.ImageInputStream; -import javax.imageio.stream.MemoryCacheImageInputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.Charset; -import java.util.Locale; - -/** - * Base64DataURLImageInputStreamSpi - * - * @author Harald Kuhr - * @author last modified by $Author: haraldk$ - * @version $Id: Base64DataURLImageInputStreamSpi.java,v 1.0 03.09.13 09:35 haraldk Exp$ - */ -public class Base64DataURLImageInputStreamSpi extends ImageInputStreamSpi { - // This is generally a bad idea, because: - // - It is bound to String.class, and not all strings are base64 encoded data URLs. - // - It's better to just create a decoder stream from the base64 stream, and use what's already in ImageIO.... - - public Base64DataURLImageInputStreamSpi() { - super("TwelveMonkeys", "0.1-BETA", String.class); - } - - @Override - public ImageInputStream createInputStreamInstance(final Object input, final boolean useCache, final File cacheDir) throws IOException { - String string = (String) input; - - InputStream stream = createStreamFromBase64(string); - - return useCache && cacheDir != null ? new FileCacheImageInputStream(stream, cacheDir) : new MemoryCacheImageInputStream(stream); - } - - private InputStream createStreamFromBase64(String string) { - if (!string.startsWith("data:")) { - throw new IllegalArgumentException(String.format("Not a data URL: %s", string)); - } - - int index = string.indexOf(';'); - if (index < 0 || !string.regionMatches(index + 1, "base64,", 0, "base64,".length())) { - throw new IllegalArgumentException(String.format("Not base64 encoded: %s", string)); - } - - int offset = index + "base64,".length() + 1; - return new DecoderStream(new StringInputStream(string.substring(offset), Charset.forName("UTF-8")), new Base64Decoder()); - } - - @Override - public boolean canUseCacheFile() { - return true; - } - - @Override - public String getDescription(Locale locale) { - return "Service provider that instantiates a FileCacheImageInputStream or MemoryCacheImageInputStream from a Base64 encoded data string"; - } -} diff --git a/sandbox/sandbox-imageio/src/test/java/com/twelvemonkeys/imageio/stream/Base64DataURLImageInputStreamTest.java b/sandbox/sandbox-imageio/src/test/java/com/twelvemonkeys/imageio/stream/Base64DataURLImageInputStreamTest.java deleted file mode 100644 index 60a8e18f..00000000 --- a/sandbox/sandbox-imageio/src/test/java/com/twelvemonkeys/imageio/stream/Base64DataURLImageInputStreamTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.twelvemonkeys.imageio.stream; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import javax.imageio.ImageIO; -import javax.imageio.spi.IIORegistry; -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; - -import static org.junit.Assert.*; - -/** - * Base64DataURLImageInputStreamTest - * - * @author Harald Kuhr - * @author last modified by $Author: haraldk$ - * @version $Id: Base64DataURLImageInputStreamTest.java,v 1.0 04.09.13 13:47 haraldk Exp$ - */ -public class Base64DataURLImageInputStreamTest { - static final String DATA = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADgAAAAiCAYAAAAKyxrjAAAKMWlDQ1BJQ0MgUHJvZmlsZQAASImdlndUU9kWh8+9N71QkhCKlNBraFICSA29SJEuKjEJEErAkAAiNkRUcERRkaYIMijggKNDkbEiioUBUbHrBBlE1HFwFBuWSWStGd+8ee/Nm98f935rn73P3Wfvfda6AJD8gwXCTFgJgAyhWBTh58WIjYtnYAcBDPAAA2wA4HCzs0IW+EYCmQJ82IxsmRP4F726DiD5+yrTP4zBAP+flLlZIjEAUJiM5/L42VwZF8k4PVecJbdPyZi2NE3OMErOIlmCMlaTc/IsW3z2mWUPOfMyhDwZy3PO4mXw5Nwn4405Er6MkWAZF+cI+LkyviZjg3RJhkDGb+SxGXxONgAoktwu5nNTZGwtY5IoMoIt43kA4EjJX/DSL1jMzxPLD8XOzFouEiSniBkmXFOGjZMTi+HPz03ni8XMMA43jSPiMdiZGVkc4XIAZs/8WRR5bRmyIjvYODk4MG0tbb4o1H9d/JuS93aWXoR/7hlEH/jD9ld+mQ0AsKZltdn6h21pFQBd6wFQu/2HzWAvAIqyvnUOfXEeunxeUsTiLGcrq9zcXEsBn2spL+jv+p8Of0NffM9Svt3v5WF485M4knQxQ143bmZ6pkTEyM7icPkM5p+H+B8H/nUeFhH8JL6IL5RFRMumTCBMlrVbyBOIBZlChkD4n5r4D8P+pNm5lona+BHQllgCpSEaQH4eACgqESAJe2Qr0O99C8ZHA/nNi9GZmJ37z4L+fVe4TP7IFiR/jmNHRDK4ElHO7Jr8WgI0IABFQAPqQBvoAxPABLbAEbgAD+ADAkEoiARxYDHgghSQAUQgFxSAtaAYlIKtYCeoBnWgETSDNnAYdIFj4DQ4By6By2AE3AFSMA6egCnwCsxAEISFyBAVUod0IEPIHLKFWJAb5AMFQxFQHJQIJUNCSAIVQOugUqgcqobqoWboW+godBq6AA1Dt6BRaBL6FXoHIzAJpsFasBFsBbNgTzgIjoQXwcnwMjgfLoK3wJVwA3wQ7oRPw5fgEVgKP4GnEYAQETqiizARFsJGQpF4JAkRIauQEqQCaUDakB6kH7mKSJGnyFsUBkVFMVBMlAvKHxWF4qKWoVahNqOqUQdQnag+1FXUKGoK9RFNRmuizdHO6AB0LDoZnYsuRlegm9Ad6LPoEfQ4+hUGg6FjjDGOGH9MHCYVswKzGbMb0445hRnGjGGmsVisOtYc64oNxXKwYmwxtgp7EHsSewU7jn2DI+J0cLY4X1w8TogrxFXgWnAncFdwE7gZvBLeEO+MD8Xz8MvxZfhGfA9+CD+OnyEoE4wJroRIQiphLaGS0EY4S7hLeEEkEvWITsRwooC4hlhJPEQ8TxwlviVRSGYkNimBJCFtIe0nnSLdIr0gk8lGZA9yPFlM3kJuJp8h3ye/UaAqWCoEKPAUVivUKHQqXFF4pohXNFT0VFysmK9YoXhEcUjxqRJeyUiJrcRRWqVUo3RU6YbStDJV2UY5VDlDebNyi/IF5UcULMWI4kPhUYoo+yhnKGNUhKpPZVO51HXURupZ6jgNQzOmBdBSaaW0b2iDtCkVioqdSrRKnkqNynEVKR2hG9ED6On0Mvph+nX6O1UtVU9Vvuom1TbVK6qv1eaoeajx1UrU2tVG1N6pM9R91NPUt6l3qd/TQGmYaYRr5Grs0Tir8XQObY7LHO6ckjmH59zWhDXNNCM0V2ju0xzQnNbS1vLTytKq0jqj9VSbru2hnaq9Q/uE9qQOVcdNR6CzQ+ekzmOGCsOTkc6oZPQxpnQ1df11Jbr1uoO6M3rGelF6hXrtevf0Cfos/ST9Hfq9+lMGOgYhBgUGrQa3DfGGLMMUw12G/YavjYyNYow2GHUZPTJWMw4wzjduNb5rQjZxN1lm0mByzRRjyjJNM91tetkMNrM3SzGrMRsyh80dzAXmu82HLdAWThZCiwaLG0wS05OZw2xljlrSLYMtCy27LJ9ZGVjFW22z6rf6aG1vnW7daH3HhmITaFNo02Pzq62ZLde2xvbaXPJc37mr53bPfW5nbse322N3055qH2K/wb7X/oODo4PIoc1h0tHAMdGx1vEGi8YKY21mnXdCO3k5rXY65vTW2cFZ7HzY+RcXpkuaS4vLo3nG8/jzGueNueq5clzrXaVuDLdEt71uUnddd457g/sDD30PnkeTx4SnqWeq50HPZ17WXiKvDq/XbGf2SvYpb8Tbz7vEe9CH4hPlU+1z31fPN9m31XfKz95vhd8pf7R/kP82/xsBWgHcgOaAqUDHwJWBfUGkoAVB1UEPgs2CRcE9IXBIYMj2kLvzDecL53eFgtCA0O2h98KMw5aFfR+OCQ8Lrwl/GGETURDRv4C6YMmClgWvIr0iyyLvRJlESaJ6oxWjE6Kbo1/HeMeUx0hjrWJXxl6K04gTxHXHY+Oj45vipxf6LNy5cDzBPqE44foi40V5iy4s1licvvj4EsUlnCVHEtGJMYktie85oZwGzvTSgKW1S6e4bO4u7hOeB28Hb5Lvyi/nTyS5JpUnPUp2Td6ePJninlKR8lTAFlQLnqf6p9alvk4LTduf9ik9Jr09A5eRmHFUSBGmCfsytTPzMoezzLOKs6TLnJftXDYlChI1ZUPZi7K7xTTZz9SAxESyXjKa45ZTk/MmNzr3SJ5ynjBvYLnZ8k3LJ/J9879egVrBXdFboFuwtmB0pefK+lXQqqWrelfrry5aPb7Gb82BtYS1aWt/KLQuLC98uS5mXU+RVtGaorH1futbixWKRcU3NrhsqNuI2ijYOLhp7qaqTR9LeCUXS61LK0rfb+ZuvviVzVeVX33akrRlsMyhbM9WzFbh1uvb3LcdKFcuzy8f2x6yvXMHY0fJjpc7l+y8UGFXUbeLsEuyS1oZXNldZVC1tep9dUr1SI1XTXutZu2m2te7ebuv7PHY01anVVda926vYO/Ner/6zgajhop9mH05+x42Rjf2f836urlJo6m06cN+4X7pgYgDfc2Ozc0tmi1lrXCrpHXyYMLBy994f9Pdxmyrb6e3lx4ChySHHn+b+O31w0GHe4+wjrR9Z/hdbQe1o6QT6lzeOdWV0iXtjusePhp4tLfHpafje8vv9x/TPVZzXOV42QnCiaITn07mn5w+lXXq6enk02O9S3rvnIk9c60vvG/wbNDZ8+d8z53p9+w/ed71/LELzheOXmRd7LrkcKlzwH6g4wf7HzoGHQY7hxyHui87Xe4Znjd84or7ldNXva+euxZw7dLI/JHh61HXb95IuCG9ybv56Fb6ree3c27P3FlzF3235J7SvYr7mvcbfjT9sV3qID0+6j068GDBgztj3LEnP2X/9H686CH5YcWEzkTzI9tHxyZ9Jy8/Xvh4/EnWk5mnxT8r/1z7zOTZd794/DIwFTs1/lz0/NOvm1+ov9j/0u5l73TY9P1XGa9mXpe8UX9z4C3rbf+7mHcTM7nvse8rP5h+6PkY9PHup4xPn34D94Tz++xtAWsAAAAJcEhZcwAACxMAAAsTAQCanBgAAAuQSURBVFiF5ZlbjF3nVcd/69u3c84+x8fjcSYxqZO6xW7r4HpkQ0ByokIVCUrVPvTBRaoqQCpCICFeeADeeOEFCcRLeQhCLRLiovICCEGEUkHaNCSkNk7jtkkd13Xi+DLjuZzbvn1r8bC/c2Ym47apyAMKS9o6+2jO7O/7f+v2X/+NmfFOXb83HFbv5PPeiUvMjLfaw0lSPRRFrEQRHRESIBEhDvelGaUZM2CkykiV83nOb62vp/se9iPYqTSths6RiXDQuX1rR4ADFDCgMsMDtRkV0Jhx23ueKYrFPvYBPJtl1c9kGe+JIlKRe25Ew8Pm5oCec6x5jw9/r832fO4/xr02UmUKbHnPiSRh2bk969cBjMIOKDNqM2raQ9dd+/le0/BMUaQLgKtZVv1qngPwpemU3z8wpCeC2wXKFqdlbJox27VIA8Q/BMQPsruqjMxY856zaeuAZtfaALrrsJrgtTrc7wb6kysNL99JuFRVO3v6TJ7zH2XJl4uCk0nC8W6XeGUFSWOsasB7fFFgRUFdlqw1DXdMmZqxpcpUldthIWjDaiDCS3XNmvfcVeWuKt0QdgAiwvyAFxsF/mo65WyaMhThwSjibJahZjQixEAsQmPGNHgVESozygDwpTsJH1xRmltJC3A1y6rP5DkvVRX/fvEinzpzBgA/mcC2x+oazJA4xuqaqbYbOSiOf5iOudw0DERIRTiXZQAUIR9c8LqjDcPX75Hz97IXq2pxf9173hfHHIkiFDgSRTgR5ommtGEpZkQhrI/3Ha/cDlF1vtfjubJkZMZHV1dZTVPKpsFvbC4e0HFCVZQosKWeJydjrjYNN0+sEscZd4HNtRs8tT3j1OwOnw3hvhJFnElTvlqW9ES47j29cOJN2FgEe/LtkHMsRxH3OYcL0QAwCx5+rWn4UJKQ0OZjY4YLRagOz1grPX0XE69mWXW+1+OlqiIW4akLF/j8uXMUatSmi0VHjS0S/MnJmBdOnAX2511XSv67qlDgsHN8vNvl4SjiWK/HphlNCGnl3mbAhio1cECEXIROALil7X954Lb3HIkiIhF8CNXKjMIMNWNcGzkgfzAcVkfjmD8ZjRiKUAO/MxiQS1teBPC0D0gRvjidLMBpU+ObBvOKmTHauMPho8e4efUyk801AB7PMv7iwfewNplQhMI0o83VMmxqXu71LeFb0YZ3GfLtjveMzHjTe+54zwNRxM93u4v8G6si4VOBbbMdBzyeZXyy06XEGNmO9yJgFHLombLkhRNnF8C08WT9Pkma0slytJmS5wPiOEXCqReAFgWHooipGglKpkZJC3RKqNBmIIKa8a2mYabKDNhW5fkjHyBqClwUI+yE8ncAbrzCySTha1XFy3XNqSThsVAHDoeixMyMk0nCDW2r3YYqZYj3eb+5q8rr3lPXJXgl6XSJ4pg0Sen1BuQHcjZuJvQPDInTncDtAC7LkCgiLwpowIm27cegoV1nHrJjM641Dc/mh4izjCiO6YqHTreNJ1XMFMxQg5cP/hi/VG9xOk33kIAtVdZUW4ATM8aq9J2jNONQYBG1GbEIY1X+aTZj/eRPt0ymHO8Dt3T/UbLXvsnB++4jS7MFwFgESRJctwtRRD4aYepQUWpv7Tohr9SMi3XNvxYFwwMOoW0lOEiyBHCYKuoVVY9rGh7aeIMrnQ5fLgou1W2JWU0Sfn0wYH0OcE2VYSi7nUCVygAuAqa7yi9AnCakScry/Q/QHx4k6w5I8mXGowmbd+5QVuWeXHJJgsu7SByDGfl4jKqjEaMxyDC8CNuqvNm07d28QqRgbR2IXIRIhIrHBJwHVePWgx/g6q0r/MZgAMAhETSkBoArgKEIcw6oZnylKHi+LHm6KEhEuNY0vP6hRxcbTrtdxlsbXPnGpQU4l/XwZoy3t2iqZvHb2gxJUyTLkE6KS9ur49q+6QC3q/nPN2YYLk6wTh9Ne5QqzLwy9Uo5nTAbb1PMRpTTtl1B2y4+vb7OH49GZCF6YoCha8Nhnn+PdTokQC5CQdto5xbFMUmckGVd6rrkwjNP4WuPqlJsbzMZjmianSY9NaNZX+fbr1/npuoeTlmbLWjXvJ99rNPhiU6Hohqj1Rg2b+2rrvssy3i1rllybeV/ta7ph+iLoa2UiQjH4pj3h/sMcAi1KYejiGuAiyLiKMY5h4gjy/r08yHiHEmWce1b00WLmFfRTIRoMOD06dOcvX+FaGkJt7TE5he+iFUVWlUUapSmVAK1tr1szZQvTaf8W1HwuwcOkInwL7MZz1UVvz0Y0AGeLkteCN/fG8eU4SA2zUgRenMPEkD1EGKBCFmwixph7r8oiojjhChqAypyQtbrkWYJvQMH+e5lz3RrfQEO9hKB+vp1qivfwaqKg7/yy2w8+eft4aB4dXhr+1cqwhLCJ7pdfi7LyJ2jMeMXul0+kmX0g6c+mmU8lmUMw/furnUHztGWpXe5LQ64NmMq4AwSgQxorG3yUfiN955GaswUEYdqBNMpVeEoiwpxEb3h8p4QbXYtlhw9uidEMcNUqdVoTPEC3lp2s2HGP85mbztEh84x25Wro0D3YtjpQbe8Z0OV44HI5tKG51ooMuo9jQgignNQVTO2NyaLIjPenvDAsZPcvHqZ6dY60I4vfjTi8nNfe1tFxtMS5sKM98Yxn+v3uR3WfyRJeCRJGKsyBj6cJHw4fN9dZA6KUNHSuxjarj90jkPOkYvwlaLAaCvgL3a7HA1FBsA3DZhSzWY0Vc2jT3x80Sae/us/XVC1ufVEiJeXOXXwGD9RVejWCD8eU1YV296zrcqElm++6T1/M53yYlUxWD5C1suhe4A4jnEuwgCvHpuN8XWNqUcb5aGNN/jNwWChMhxPEsbhsOIOsGUGquQiOBEe63QoA/+szXg4jvnuN59f9MJqNqM/XGL5/gcoZ6M2/IBIZB9VS0SwqsLKEitrdFflrMKEroEWQkvtAARBm5qoGOPSlKzXD43eaHo55hWtG7z3HBu168Ui/O3y8qLRN3MPHnaOsSqJCKUqvTCi1IEA98JIMremqqnqivVbN5mNJoGqQX+Q76NqAFrXMJmhRYGOx0zUKNBW7mBnquiIcCSOoaqQyIE4EBaegzZnLVA1U8/9b3ybY50OfzYa7aNqzHMwF6EXRfREFtLCW8n2ShRRXf5Pbh5fxcURvmmoAKajAOM65XS6j6o1Zlhdo6poUbTgTBc6ThGe34R8XE0SRp0Oz3rFxWHKUKjLmnuR7e8tPcj76y1+vN/fQ7bXvMfmALsi/FdV8clOl2XnFuMR7B+X1pMMlZq6mFE2Ht/v0/iGqqqo63ofVSsALVvAUzUm6C7ZcUc4mheenggPxzErs01ms13jUjHbNy4BPLJ5g0vfZ1xKdzf6Z8qSS1V1z4E3lzZhz3d7zF55kRdOnMXFCdq0QKvJhLHdZTKa0J20VG0uJnUA1+n8wIG32ZWLAB+M223NB95H16/+0IH3Y90uj2fZvoFXTqdpdb7X4wvjMTPgn7/+dT5/7hyfywd7JIu5vvlWyWK3ba7doBhtMtlc41Sa7pEsgHdUsshEvq9kMVbl8OGatbWE+GJZpn+4tFSdSlOeLcuF6NRxQqKtFxU4GAmVtiB/Le/DKy/uEZ3mNrOM02nKZ/OcDVVmZlz1nq+WJeve/69Ep26YHSPgaOCePhxaw47sWAD9RLhGyMG/m06Zy4Z/f+ECnzpzhiyOkTwHvyMbJnGMFgW+CSCBv3ztGwvZ8PhcNuz12FBlW5UrqrzRNEzMuNo0bUv6Ee1ns4z3xTGHnCOjlQ3novPcAXPtpqbt34eztjPEABfLMv2jQ4eqU2nKR1ZXOZkEMp3n+4Rf8Z6eKlOFO6Y80e3yUwHMZpA2CKe+EkXcCu1HzRg4x8rbEH5fD+r2PuGXHW6pu8QqQnjOhd/SjFfHSmPCu166///z8mW3vZten72jLxv/L74A/R9e1ZBJD0Hq0AAAAABJRU5ErkJggg=="; - static final Base64DataURLImageInputStreamSpi provider = new Base64DataURLImageInputStreamSpi(); - - @Before - public void init() { - IIORegistry.getDefaultInstance().registerServiceProvider(provider); - } - - @After - public void destroy() { - IIORegistry.getDefaultInstance().deregisterServiceProvider(provider); - } - - @Test - public void testRead() throws IOException, InvocationTargetException, InterruptedException { - BufferedImage image = ImageIO.read(ImageIO.createImageInputStream(DATA)); - - assertNotNull(image); - assertEquals(56, image.getWidth()); - assertEquals(34, image.getHeight()); - } -} diff --git a/sandbox/sandbox-servlet/pom.xml b/sandbox/sandbox-servlet/pom.xml deleted file mode 100644 index d2bb73de..00000000 --- a/sandbox/sandbox-servlet/pom.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - - - 4.0.0 - - com.twelvemonkeys.sandbox - sandbox - 3.1-SNAPSHOT - - sandbox-servlet - jar - TwelveMonkeys :: Sandbox :: Servlet - - The TwelveMonkeys Servlet Sandbox. Experimental stuff. Old stuff that didn't cut it. - - - - - com.twelvemonkeys.common - common-lang - compile - - - com.twelvemonkeys.common - common-io - compile - - - com.twelvemonkeys.common - common-image - compile - - - com.twelvemonkeys.servlet - servlet - compile - - - - - javax.servlet - servlet-api - 2.4 - provided - - - - javax.servlet - jsp-api - 2.0 - provided - - - - diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/image/TextRenderer.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/image/TextRenderer.java deleted file mode 100755 index 69530349..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/image/TextRenderer.java +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright (c) 2008, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.twelvemonkeys.servlet.image; - -import com.twelvemonkeys.lang.StringUtil; -import com.twelvemonkeys.servlet.ServletUtil; - -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; -import java.awt.*; -import java.awt.geom.Rectangle2D; - -/** - * This servlet is capable of rendereing a text string and output it as an - * image. The text can be rendered in any given font, size, - * style or color, into an image, and output it as a GIF, JPEG or PNG image, - * with optional caching of the rendered image files. - * - *


- * - * Parameters:
- *

- *
{@code text}
- *
string, the text string to render. - *
{@code width}
- *
integer, the width of the image - *
{@code height}
- *
integer, the height of the image - *
{@code fontFamily}
- *
string, the name of the font family. - * Default is {@code "Helvetica"}. - *
{@code fontSize}
- *
integer, the size of the font. Default is {@code 12}. - *
{@code fontStyle}
- *
string, the tyle of the font. Can be one of the constants - * {@code plain} (default), {@code bold}, {@code italic} or - * {@code bolditalic}. Any other will result in {@code plain}. - *
{@code fgcolor}
- *
color (HTML form, {@code #RRGGBB}), or color constant from - * {@link java.awt.Color}, default is {@code "black"}. - *
{@code bgcolor}
- *
color (HTML form, {@code #RRGGBB}), or color constant from - * {@link java.awt.Color}, default is {@code "transparent"}. - * Note that the hash character ({@code "#"}) used in colors must be - * escaped as {@code %23} in the query string. See - * {@link StringUtil#toColor(String)}, examples. - * - * - * - *
{@code cache}
- *
boolean, {@code true} if you want to cache the result - * to disk (default). - * - *
{@code compression}
- *
float, the optional compression ratio for the output image. For JPEG - * images, the quality is the inverse of the compression ratio. See - * {@link #JPEG_DEFAULT_COMPRESSION_LEVEL}, - * {@link #PNG_DEFAULT_COMPRESSION_LEVEL}. - *
Applies to JPEG and PNG images only. - * - *
{@code dither}
- *
enumerated, one of {@code NONE}, {@code DEFAULT} or - * {@code FS}, if you want to dither the result ({@code DEFAULT} is - * default). - * {@code FS} will produce the best results, but it's slower. - *
Use in conjuction with {@code indexed}, {@code palette} - * and {@code websafe}. - *
Applies to GIF and PNG images only. - * - *
{@code fileName}
- *
string, an optional filename. If not set, the path after the servlet - * ({@link HttpServletRequest#getPathInfo}) will be used for the cache - * filename. See {@link #getCacheFile(ServletRequest)}, - * {@link #getCacheRoot}. - * - *
{@code height}
- *
integer, the height of the image. - * - *
{@code width}
- *
integer, the width of the image. - * - *
{@code indexed}
- *
integer, the number of colors in the resulting image, or -1 (default). - * If the value is set and positive, the image will use an - * {@code IndexColorModel} with - * the number of colors specified. Otherwise the image will be true color. - *
Applies to GIF and PNG images only. - * - *
{@code palette}
- *
string, an optional filename. If set, the image will use IndexColorModel - * with a palette read from the given file. - *
Applies to GIF and PNG images only. - * - *
{@code websafe}
- *
boolean, {@code true} if you want the result to use the 216 color - * websafe palette (default is false). - *
Applies to GIF and PNG images only. - *
- * - * @example - * <IMG src="/text/test.gif?height=40&width=600 - * &fontFamily=TimesRoman&fontSize=30&fontStyle=italic&fgcolor=%23990033 - * &bgcolor=%23cccccc&text=the%20quick%20brown%20fox%20jumps%20over%20the - * %20lazy%20dog&cache=false" /> - * - * @example - * <IMG src="/text/test.jpg?height=40&width=600 - * &fontFamily=TimesRoman&fontSize=30&fontStyle=italic&fgcolor=black - * &bgcolor=%23cccccc&text=the%20quick%20brown%20fox%20jumps%20over%20the - * %20lazy%20dog&compression=3&cache=false" /> - * - * @example - * <IMG src="/text/test.png?height=40&width=600 - * &fontFamily=TimesRoman&fontSize=30&fontStyle=italic&fgcolor=%23336699 - * &bgcolor=%23cccccc&text=the%20quick%20brown%20fox%20jumps%20over%20the - * %20lazy%20dog&cache=true" /> - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * @version $Id: TextRenderer.java#2 $ - */ - -class TextRenderer /*extends ImageServlet implements ImagePainterServlet*/ { - // TODO: Create something usable out of this piece of old junk.. ;-) - // It just needs a graphics object to write onto - // Alternatively, defer, and compute the size needed - // Or, make it a filter... - - /** {@code "italic"} */ - public final static String FONT_STYLE_ITALIC = "italic"; - /** {@code "plain"} */ - public final static String FONT_STYLE_PLAIN = "plain"; - /** {@code "bold"} */ - public final static String FONT_STYLE_BOLD = "bold"; - - /** {@code text} */ - public final static String PARAM_TEXT = "text"; - /** {@code marginLeft} */ - public final static String PARAM_MARGIN_LEFT = "marginLeft"; - /** {@code marginTop} */ - public final static String PARAM_MARGIN_TOP = "marginTop"; - /** {@code fontFamily} */ - public final static String PARAM_FONT_FAMILY = "fontFamily"; - /** {@code fontSize} */ - public final static String PARAM_FONT_SIZE = "fontSize"; - /** {@code fontStyle} */ - public final static String PARAM_FONT_STYLE = "fontStyle"; - /** {@code textRotation} */ - public final static String PARAM_TEXT_ROTATION = "textRotation"; - /** {@code textRotation} */ - public final static String PARAM_TEXT_ROTATION_UNITS = "textRotationUnits"; - - /** {@code bgcolor} */ - public final static String PARAM_BGCOLOR = "bgcolor"; - /** {@code fgcolor} */ - public final static String PARAM_FGCOLOR = "fgcolor"; - - protected final static String ROTATION_DEGREES = "DEGREES"; - protected final static String ROTATION_RADIANS = "RADIANS"; - - /** - * Creates the TextRender servlet. - */ - - public TextRenderer() { - } - - /** - * Renders the text string for this servlet request. - */ - private void paint(ServletRequest pReq, Graphics2D pRes, int pWidth, int pHeight) - throws ImageServletException { - - // Get parameters - String text = pReq.getParameter(PARAM_TEXT); - String[] lines = StringUtil.toStringArray(text, "\n\r"); - - String fontFamily = pReq.getParameter(PARAM_FONT_FAMILY); - String fontSize = pReq.getParameter(PARAM_FONT_SIZE); - String fontStyle = pReq.getParameter(PARAM_FONT_STYLE); - - String bgcolor = pReq.getParameter(PARAM_BGCOLOR); - String fgcolor = pReq.getParameter(PARAM_FGCOLOR); - - // TODO: Make them static.. - pRes.addRenderingHints(new RenderingHints(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON)); - pRes.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY)); - pRes.addRenderingHints(new RenderingHints(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY)); - // pRes.addRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)); - - //System.out.println(pRes.getBackground()); - - // Clear area with bgcolor - if (!StringUtil.isEmpty(bgcolor)) { - pRes.setBackground(StringUtil.toColor(bgcolor)); - pRes.clearRect(0, 0, pWidth, pHeight); - - //System.out.println(pRes.getBackground()); - } - - // Create and set font - Font font = new Font( - fontFamily != null ? fontFamily : "Helvetica", - getFontStyle(fontStyle), - fontSize != null ? Integer.parseInt(fontSize) : 12 - ); - pRes.setFont(font); - - // Set rotation - double angle = getAngle(pReq); - pRes.rotate(angle, pWidth / 2.0, pHeight / 2.0); - - // Draw string in fgcolor - pRes.setColor(fgcolor != null ? StringUtil.toColor(fgcolor) : Color.black); - - float x = ServletUtil.getFloatParameter(pReq, PARAM_MARGIN_LEFT, Float.MIN_VALUE); - Rectangle2D[] bounds = new Rectangle2D[lines.length]; - if (x <= Float.MIN_VALUE) { - // Center - float longest = 0f; - for (int i = 0; i < lines.length; i++) { - bounds[i] = font.getStringBounds(lines[i], pRes.getFontRenderContext()); - if (bounds[i].getWidth() > longest) { - longest = (float) bounds[i].getWidth(); - } - } - - //x = (float) ((pWidth - bounds.getWidth()) / 2f); - x = (float) ((pWidth - longest) / 2f); - - //System.out.println("marginLeft: " + x); - } - //else { - //System.out.println("marginLeft (from param): " + x); - //} - - float y = ServletUtil.getFloatParameter(pReq, PARAM_MARGIN_TOP, Float.MIN_VALUE); - float lineHeight = (float) (bounds[0] != null ? - bounds[0].getHeight() : font.getStringBounds(lines[0], pRes.getFontRenderContext()).getHeight()); - - if (y <= Float.MIN_VALUE) { - // Center - y = (float) ((pHeight - lineHeight) / 2f) - - (lineHeight * (lines.length - 2.5f) / 2f); - - //System.out.println("marginTop: " + y); - } - else { - // Todo: Correct for font height? - y += font.getSize2D(); - //System.out.println("marginTop (from param):" + y); - - } - - //System.out.println("Font size: " + font.getSize2D()); - //System.out.println("Line height: " + lineHeight); - - // Draw - for (int i = 0; i < lines.length; i++) { - pRes.drawString(lines[i], x, y + lineHeight * i); - } - } - - /** - * Returns the font style constant. - * - * @param pStyle a string containing either the word {@code "plain"} or one - * or more of {@code "bold"} and {@code italic}. - * @return the font style constant as defined in {@link Font}. - * - * @see Font#PLAIN - * @see Font#BOLD - * @see Font#ITALIC - */ - private int getFontStyle(String pStyle) { - if (pStyle == null || StringUtil.containsIgnoreCase(pStyle, FONT_STYLE_PLAIN)) { - return Font.PLAIN; - } - - // Try to find bold/italic - int style = Font.PLAIN; - if (StringUtil.containsIgnoreCase(pStyle, FONT_STYLE_BOLD)) { - style |= Font.BOLD; - } - if (StringUtil.containsIgnoreCase(pStyle, FONT_STYLE_ITALIC)) { - style |= Font.ITALIC; - } - - return style; - } - - /** - * Gets the angle of rotation from the request. - * - * @param pRequest the servlet request to get parameters from - * @return the angle in radians. - */ - private double getAngle(ServletRequest pRequest) { - // Get angle - double angle = ServletUtil.getDoubleParameter(pRequest, PARAM_TEXT_ROTATION, 0.0); - - // Convert to radians, if needed - String units = pRequest.getParameter(PARAM_TEXT_ROTATION_UNITS); - if (!StringUtil.isEmpty(units) && ROTATION_DEGREES.equalsIgnoreCase(units)) { - angle = Math.toRadians(angle); - } - - return angle; - } -} \ No newline at end of file diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/Droplet.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/Droplet.java deleted file mode 100755 index 261733c7..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/Droplet.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2002 TwelveMonkeys. - * All rights reserved. - * - * $Log: Droplet.java,v $ - * Revision 1.3 2003/10/06 14:25:19 WMHAKUR - * Code clean-up only. - * - * Revision 1.2 2002/10/18 14:12:16 WMHAKUR - * Now, it even compiles. :-/ - * - * Revision 1.1 2002/10/18 14:02:16 WMHAKUR - * Moved to com.twelvemonkeys.servlet.jsp.droplet - * - * - */ - -package com.twelvemonkeys.servlet.jsp.droplet; - -import com.twelvemonkeys.servlet.jsp.droplet.taglib.IncludeTag; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.jsp.PageContext; -import java.io.IOException; - -/** - * Dynamo Droplet like Servlet. - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * - * @version $Revision: #1 $, ($Date: 2008/05/05 $) - * - */ -public abstract class Droplet extends HttpServlet implements JspFragment { - - public abstract void service(PageContext pPageContext) - throws ServletException, IOException; - - /** - * Services a parameter. Programatically equivalent to the - * JSP tag. - */ - public void serviceParameter(String pParameter, PageContext pPageContext) throws ServletException, IOException { - Object param = pPageContext.getRequest().getAttribute(pParameter); - - if (param != null) { - if (param instanceof Param) { - ((Param) param).service(pPageContext); - } - else { - pPageContext.getOut().print(param); - } - } - else { - // Try to get value from parameters - Object obj = pPageContext.getRequest().getParameter(pParameter); - - // Print parameter or default value - pPageContext.getOut().print((obj != null) ? obj : ""); - } - } - - /** - * "There's no need to override this method." :-) - */ - final public void service(HttpServletRequest pRequest, HttpServletResponse pResponse) throws ServletException, IOException { - PageContext pageContext = (PageContext) pRequest.getAttribute(IncludeTag.PAGE_CONTEXT); - - // TODO: What if pageContext == null - service(pageContext); - } -} diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/JspFragment.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/JspFragment.java deleted file mode 100755 index 50b11b64..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/JspFragment.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2002 TwelveMonkeys. - * All rights reserved. - * - * $Log: JspFragment.java,v $ - * Revision 1.2 2003/10/06 14:25:36 WMHAKUR - * Code clean-up only. - * - * Revision 1.1 2002/10/18 14:02:16 WMHAKUR - * Moved to com.twelvemonkeys.servlet.jsp.droplet - * - * - */ - -package com.twelvemonkeys.servlet.jsp.droplet; - -import javax.servlet.ServletException; -import javax.servlet.jsp.PageContext; -import java.io.IOException; - -/** - * Interface for JSP sub pages or page fragments to implement. - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * - * @version $Revision: #1 $, ($Date: 2008/05/05 $) - */ -public interface JspFragment { - - /** - * Services a sub page or a page fragment inside another page - * (or PageContext). - * - * @param pContext the PageContext that is used to render the subpage. - * - * @throws ServletException if an exception occurs that interferes with the - * subpage's normal operation - * @throws IOException if an input or output exception occurs - */ - public void service(PageContext pContext) throws ServletException, IOException; -} diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/Oparam.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/Oparam.java deleted file mode 100755 index 87c29ce7..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/Oparam.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.twelvemonkeys.servlet.jsp.droplet; - -import javax.servlet.ServletException; -import javax.servlet.jsp.PageContext; -import java.io.IOException; - -/** - * Oparam (Open parameter) - */ -public class Oparam extends Param implements JspFragment { - /** - * Creates an Oparam. - * - * @param pValue the value of the parameter - */ - public Oparam(String pValue) { - super(pValue); - } - - public void service(PageContext pContext) throws ServletException, IOException { - pContext.getServletContext().log("Service subpage " + pContext.getServletContext().getRealPath(value)); - - pContext.include(value); - } -} - diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/Param.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/Param.java deleted file mode 100755 index 74fe73d9..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/Param.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.twelvemonkeys.servlet.jsp.droplet; - -import javax.servlet.ServletException; -import javax.servlet.jsp.JspWriter; -import javax.servlet.jsp.PageContext; -import java.io.IOException; - -/** - * Param - */ -public class Param implements JspFragment { - - /** The value member field. */ - protected String value = null; - - /** - * Creates a Param. - * - * @param pValue the value of the parameter - */ - public Param(String pValue) { - value = pValue; - } - - /** - * Gets the value of the parameter. - */ - public String getValue() { - return value; - } - - /** - * Services the page fragment. This version simply prints the value of - * this parameter to teh PageContext's out. - */ - public void service(PageContext pContext) - throws ServletException, IOException { - JspWriter writer = pContext.getOut(); - writer.print(value); - } -} diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/package-info.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/package-info.java deleted file mode 100755 index 0f10f187..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/package-info.java +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Dynamo Droplet-like functionality for JSP. - * - * This package is early beta, not for commercial use! :-) - * Read: The interfaces and classes in this package (and subpackages) will be - * developed and modified for a while. - * - */ -package com.twelvemonkeys.servlet.jsp.droplet; \ No newline at end of file diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/IncludeTag.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/IncludeTag.java deleted file mode 100755 index d25dbda5..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/IncludeTag.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (c) 2002 TwelveMonkeys. - * All rights reserved. - * - * $Log: IncludeTag.java,v $ - * Revision 1.2 2003/10/06 14:25:36 WMHAKUR - * Code clean-up only. - * - * Revision 1.1 2002/10/18 14:03:09 WMHAKUR - * Moved to com.twelvemonkeys.servlet.jsp.droplet.taglib - * - * - */ - -package com.twelvemonkeys.servlet.jsp.droplet.taglib; - -import com.twelvemonkeys.servlet.jsp.taglib.ExTagSupport; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.jsp.JspException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; - -/** - * Include tag tag that emulates ATG Dynamo Droplet tag JHTML behaviour for - * JSP. - * - * @author Thomas Purcell (CSC Australia) - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * - * @version $Revision: #1 $, ($Date: 2008/05/05 $) - * - */ -public class IncludeTag extends ExTagSupport { - /** - * This will contain the names of all the parameters that have been - * added to the PageContext.REQUEST_SCOPE scope by this tag. - */ - private ArrayList parameterNames = null; - - /** - * If any of the parameters we insert for this tag already exist, then - * we back up the older parameter in this {@code HashMap} and - * restore them when the tag is finished. - */ - private HashMap oldParameters = null; - - /** - * This is the URL for the JSP page that the parameters contained in this - * tag are to be inserted into. - */ - private String page; - - /** - * The name of the PageContext attribute - */ - public final static String PAGE_CONTEXT = "com.twelvemonkeys.servlet.jsp.PageContext"; - - /** - * Sets the value for the JSP page to insert the parameters into. This - * will be set by the tag attribute within the original JSP page. - * - * @param pPage The URL for the JSP page to insert parameters into. - */ - public void setPage(String pPage) { - page = pPage; - } - - /** - * Adds a parameter to the {@code PageContext.REQUEST_SCOPE} scope. - * If a parameter with the same name as {@code pName} already exists, - * then the old parameter is first placed in the {@code OldParameters} - * member variable. When this tag is finished, the old value will be - * restored. - * - * @param pName The name of the new parameter to be stored in the - * {@code PageContext.REQUEST_SCOPE} scope. - * @param pValue The value for the parmeter to be stored in the {@code - * PageContext.REQUEST_SCOPE} scope. - */ - public void addParameter(String pName, Object pValue) { - // Check that we haven't already saved this parameter - if (!parameterNames.contains(pName)) { - parameterNames.add(pName); - - // Now check if this parameter already exists in the page. - Object obj = getRequest().getAttribute(pName); - if (obj != null) { - oldParameters.put(pName, obj); - } - } - - // Finally, insert the parameter in the request scope. - getRequest().setAttribute(pName, pValue); - } - - /** - * This is the method called when the JSP interpreter first hits the tag - * associated with this class. This method will firstly determine whether - * the page referenced by the {@code page} attribute exists. If the - * page doesn't exist, this method will throw a {@code JspException}. - * If the page does exist, this method will hand control over to that JSP - * page. - * - * @exception JspException - */ - public int doStartTag() throws JspException { - oldParameters = new HashMap(); - parameterNames = new ArrayList(); - - return EVAL_BODY_INCLUDE; - } - - /** - * This method is called when the JSP page compiler hits the end tag. By - * now all the data should have been passed and parameters entered into - * the {@code PageContext.REQUEST_SCOPE} scope. This method includes - * the JSP page whose URL is stored in the {@code mPage} member - * variable. - * - * @exception JspException - */ - public int doEndTag() throws JspException { - String msg; - - try { - Iterator iterator; - String parameterName; - - // -- Harald K 20020726 - // Include the page, in place - //getDispatcher().include(getRequest(), getResponse()); - addParameter(PAGE_CONTEXT, pageContext); // Will be cleared later - pageContext.include(page); - - // Remove all the parameters that were added to the request scope - // for this insert tag. - iterator = parameterNames.iterator(); - - while (iterator.hasNext()) { - parameterName = iterator.next(); - - getRequest().removeAttribute(parameterName); - } - - iterator = oldParameters.keySet().iterator(); - - // Restore the parameters we temporarily replaced (if any). - while (iterator.hasNext()) { - parameterName = iterator.next(); - - getRequest().setAttribute(parameterName, oldParameters.get(parameterName)); - } - - return super.doEndTag(); - } - catch (IOException ioe) { - msg = "Caught an IOException while including " + page - + "\n" + ioe.toString(); - log(msg, ioe); - throw new JspException(msg); - } - catch (ServletException se) { - msg = "Caught a ServletException while including " + page - + "\n" + se.toString(); - log(msg, se); - throw new JspException(msg); - } - } - - /** - * Free up the member variables that we've used throughout this tag. - */ - protected void clearServiceState() { - oldParameters = null; - parameterNames = null; - } - - /** - * Returns the request dispatcher for the JSP page whose URL is stored in - * the {@code mPage} member variable. - * - * @return The RequestDispatcher for the JSP page whose URL is stored in - * the {@code mPage} member variable. - */ - /* - private RequestDispatcher getDispatcher() { - return getRequest().getRequestDispatcher(page); - } - */ - - /** - * Returns the HttpServletRequest object for the current user request. - * - * @return The HttpServletRequest object for the current user request. - */ - private HttpServletRequest getRequest() { - return (HttpServletRequest) pageContext.getRequest(); - } - - /** - * Returns the HttpServletResponse object for the current user request. - * - * @return The HttpServletResponse object for the current user request. - */ - private HttpServletResponse getResponse() { - return (HttpServletResponse) pageContext.getResponse(); - } -} diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/NestingHandler.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/NestingHandler.java deleted file mode 100755 index 71278ee6..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/NestingHandler.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2002 TwelveMonkeys. - * All rights reserved. - * - * $Log: NestingHandler.java,v $ - * Revision 1.4 2003/10/06 14:25:44 WMHAKUR - * Code clean-up only. - * - * Revision 1.3 2003/08/04 15:26:30 WMHAKUR - * Code clean-up. - * - * Revision 1.2 2002/10/18 14:28:07 WMHAKUR - * Fixed package error. - * - * Revision 1.1 2002/10/18 14:03:09 WMHAKUR - * Moved to com.twelvemonkeys.servlet.jsp.droplet.taglib - * - * - */ - -package com.twelvemonkeys.servlet.jsp.droplet.taglib; - -import com.twelvemonkeys.lang.StringUtil; - -import org.xml.sax.*; -import org.xml.sax.helpers.DefaultHandler; - -/** - * A SAX handler that returns an exception if the nesting of - * {@code param}, {@code oparam}, {@code droplet} and - * {@code valueof} is not correct. - * - * Based on the NestingHandler.java, - * taken from More Servlets and JavaServer Pages - * from Prentice Hall and Sun Microsystems Press, - * http://www.moreservlets.com/. - * © 2002 Marty Hall; may be freely used or adapted. - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * - * @version $Revision: #1 $, ($Date: 2008/05/05 $) - */ -public class NestingHandler extends DefaultHandler { - private String includeTagName = "include"; - private String paramTagName = "param"; - private String openParamTagName = "oparam"; - - //private Stack mParents = new Stack(); - - private boolean inIncludeTag = false; - - private String namespacePrefix = null; - private String namespaceURI = null; - - private NestingValidator validator = null; - - public NestingHandler(String pNamespacePrefix, String pNameSpaceURI, - NestingValidator pValidator) { - namespacePrefix = pNamespacePrefix; - namespaceURI = pNameSpaceURI; - - validator = pValidator; - } - - public void startElement(String pNamespaceURI, String pLocalName, - String pQualifiedName, Attributes pAttributes) - throws SAXException { - String namespacePrefix = !StringUtil.isEmpty(pNamespaceURI) - ? getNSPrefixFromURI(pNamespaceURI) - : getNamespacePrefix(pQualifiedName); - - String localName = !StringUtil.isEmpty(pLocalName) - ? pLocalName : getLocalName(pQualifiedName); - /* - if (namespacePrefix.equals(namespacePrefix)) { - System.out.println("startElement:\nnamespaceURI=" + pNamespaceURI - + " namespacePrefix=" + namespacePrefix - + " localName=" + localName - + " qName=" + pQualifiedName - + " attributes=" + pAttributes); - } - */ - if (localName.equals(includeTagName)) { - // include - //System.out.println("<" + namespacePrefix + ":" - // + includeTagName + ">"); - if (inIncludeTag) { - validator.reportError("Cannot nest " + namespacePrefix + ":" - + includeTagName); - } - inIncludeTag = true; - } - else if (localName.equals(paramTagName)) { - // param - //System.out.println("<" + namespacePrefix + ":" - // + paramTagName + "/>"); - if (!inIncludeTag) { - validator.reportError(this.namespacePrefix + ":" - + paramTagName - + " can only appear within " - + this.namespacePrefix + ":" - + includeTagName); - } - } - else if (localName.equals(openParamTagName)) { - // oparam - //System.out.println("<" + namespacePrefix + ":" - // + openParamTagName + ">"); - if (!inIncludeTag) { - validator.reportError(this.namespacePrefix + ":" - + openParamTagName - + " can only appear within " - + this.namespacePrefix + ":" - + includeTagName); - } - inIncludeTag = false; - } - else { - // Only jsp:text allowed inside include! - if (inIncludeTag && !localName.equals("text")) { - validator.reportError(namespacePrefix + ":" + localName - + " can not appear within " - + this.namespacePrefix + ":" - + includeTagName); - } - } - } - - public void endElement(String pNamespaceURI, - String pLocalName, - String pQualifiedName) - throws SAXException { - String namespacePrefix = !StringUtil.isEmpty(pNamespaceURI) - ? getNSPrefixFromURI(pNamespaceURI) - : getNamespacePrefix(pQualifiedName); - - String localName = !StringUtil.isEmpty(pLocalName) - ? pLocalName : getLocalName(pQualifiedName); - /* - if (namespacePrefix.equals(namespacePrefix)) { - System.out.println("endElement:\nnamespaceURI=" + pNamespaceURI - + " namespacePrefix=" + namespacePrefix - + " localName=" + localName - + " qName=" + pQualifiedName); - } - */ - if (namespacePrefix.equals(this.namespacePrefix) - && localName.equals(includeTagName)) { - - //System.out.println(""); - - inIncludeTag = false; - } - else if (namespacePrefix.equals(this.namespacePrefix) - && localName.equals(openParamTagName)) { - - //System.out.println(""); - - inIncludeTag = true; // assuming no errors before this... - } - } - - /** - * Stupid broken namespace-support "fix".. - */ - - private String getNSPrefixFromURI(String pNamespaceURI) { - return (pNamespaceURI.equals(namespaceURI) - ? namespacePrefix : ""); - } - - private String getNamespacePrefix(String pQualifiedName) { - return pQualifiedName.substring(0, pQualifiedName.indexOf(':')); - } - - private String getLocalName(String pQualifiedName) { - return pQualifiedName.substring(pQualifiedName.indexOf(':') + 1); - } -} - diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/NestingValidator.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/NestingValidator.java deleted file mode 100755 index 15e5fe7f..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/NestingValidator.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2002 TwelveMonkeys. - * All rights reserved. - * - * $Log: NestingValidator.java,v $ - * Revision 1.4 2003/08/04 15:26:40 WMHAKUR - * Code clean-up. - * - * Revision 1.3 2002/11/18 14:12:43 WMHAKUR - * *** empty log message *** - * - * Revision 1.2 2002/10/18 14:28:07 WMHAKUR - * Fixed package error. - * - * Revision 1.1 2002/10/18 14:03:09 WMHAKUR - * Moved to com.twelvemonkeys.servlet.jsp.droplet.taglib - * - * - */ - -package com.twelvemonkeys.servlet.jsp.droplet.taglib; - -import org.xml.sax.InputSource; -import org.xml.sax.helpers.DefaultHandler; - -import javax.servlet.jsp.tagext.PageData; -import javax.servlet.jsp.tagext.TagLibraryValidator; -import javax.servlet.jsp.tagext.ValidationMessage; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; -import java.util.ArrayList; -import java.util.List; - -/** - * A validator that verifies that tags follow - * proper nesting order. - *

- * Based on NestingValidator.java, - * taken from More Servlets and JavaServer Pages - * from Prentice Hall and Sun Microsystems Press, - * http://www.moreservlets.com/. - * © 2002 Marty Hall; may be freely used or adapted. - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * - * @version $Revision: #1 $, ($Date: 2008/05/05 $) - * - */ -public class NestingValidator extends TagLibraryValidator { - - private List errors = new ArrayList(); - - /** - * - */ - public ValidationMessage[] validate(String pPrefix, String pURI, PageData pPage) { - - //System.out.println("Validating " + pPrefix + " (" + pURI + ") for " - // + pPage + "."); - - // Pass the parser factory in on the command line with - // -D to override the use of the Apache parser. - - DefaultHandler handler = new NestingHandler(pPrefix, pURI, this); - SAXParserFactory factory = SAXParserFactory.newInstance(); - - try { - // FileUtil.copy(pPage.getInputStream(), System.out); - - SAXParser parser = factory.newSAXParser(); - InputSource source = - new InputSource(pPage.getInputStream()); - - // Parse, handler will use callback to report errors - parser.parse(source, handler); - - - } - catch (Exception e) { - String errorMessage = e.getMessage(); - - reportError(errorMessage); - } - - // Return any errors and exceptions, empty array means okay - return errors.toArray(new ValidationMessage[errors.size()]); - } - - /** - * Callback method for the handler to report errors - */ - public void reportError(String pMessage) { - // The first argument to the ValidationMessage - // constructor can be a tag ID. Since tag IDs - // are not universally supported, use null for - // portability. The important part is the second - // argument: the error message. - errors.add(new ValidationMessage(null, pMessage)); - } -} - diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/OparamTag.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/OparamTag.java deleted file mode 100755 index 62bf52d2..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/OparamTag.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright (c) 2002 TwelveMonkeys. - * All rights reserved. - * - * $Log: OparamTag.java,v $ - * Revision 1.4 2003/10/06 14:25:53 WMHAKUR - * Code clean-up only. - * - * Revision 1.3 2002/11/18 14:12:43 WMHAKUR - * *** empty log message *** - * - * Revision 1.2 2002/11/07 12:20:14 WMHAKUR - * Updated to reflect changes in com.twelvemonkeys.util.*Util - * - * Revision 1.1 2002/10/18 14:03:09 WMHAKUR - * Moved to com.twelvemonkeys.servlet.jsp.droplet.taglib - * - * - */ - -package com.twelvemonkeys.servlet.jsp.droplet.taglib; - -import com.twelvemonkeys.io.FileUtil; -import com.twelvemonkeys.lang.StringUtil; -import com.twelvemonkeys.servlet.jsp.droplet.Oparam; -import com.twelvemonkeys.servlet.jsp.taglib.BodyReaderTag; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.jsp.JspException; -import java.io.File; -import java.io.IOException; - -/** - * Open parameter tag that emulates ATG Dynamo JHTML behaviour for JSP. - * - * @author Thomas Purcell (CSC Australia) - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * @version $Id: jsp/droplet/taglib/OparamTag.java#1 $ - */ -public class OparamTag extends BodyReaderTag { - - protected final static String COUNTER = "com.twelvemonkeys.servlet.jsp.taglib.OparamTag.counter"; - - private File subpage = null; - - /** - * This is the name of the parameter to be inserted into the {@code - * PageContext.REQUEST_SCOPE} scope. - */ - private String parameterName = null; - - private String language = null; - - private String prefix = null; - - /** - * This method allows the JSP page to set the name for the parameter by - * using the {@code name} tag attribute. - * - * @param pName The name for the parameter to insert into the {@code - * PageContext.REQUEST_SCOPE} scope. - */ - public void setName(String pName) { - parameterName = pName; - } - - public void setLanguage(String pLanguage) { - //System.out.println("setLanguage:"+pLanguage); - language = pLanguage; - } - - public void setPrefix(String pPrefix) { - //System.out.println("setPrefix:"+pPrefix); - prefix = pPrefix; - } - - /** - * Ensure that the tag implemented by this class is enclosed by an {@code IncludeTag}. - * If the tag is not enclosed by an {@code IncludeTag} then a {@code JspException} is thrown. - * - * @return If this tag is enclosed within an {@code IncludeTag}, then the default return value - * from this method is the {@code TagSupport.EVAL_BODY_TAG} value. - * - * @throws JspException - */ - public int doStartTag() throws JspException { - //checkEnclosedInIncludeTag(); // Moved to TagLibValidator - - // Get request - HttpServletRequest request = (HttpServletRequest) pageContext.getRequest(); - - // Get filename - subpage = createFileNameFromRequest(request); - - // Get include tag, and add to parameters - IncludeTag includeTag = (IncludeTag) getParent(); - includeTag.addParameter(parameterName, new Oparam(subpage.getName())); - - // if ! subpage.exist || jsp newer than subpage, write new - File jsp = new File(pageContext.getServletContext().getRealPath(request.getServletPath())); - - if (!subpage.exists() || jsp.lastModified() > subpage.lastModified()) { - return EVAL_BODY_BUFFERED; - } - - // No need to evaluate body again! - return SKIP_BODY; - } - - /** - * This is the method responsible for actually testing that the tag - * implemented by this class is enclosed within an {@code IncludeTag}. - * - * @exception JspException - */ - /* - protected void checkEnclosedInIncludeTag() throws JspException { - Tag parentTag = getParent(); - - if ((parentTag != null) && (parentTag instanceof IncludeTag)) { - return; - } - - String msg = "A class that extends EnclosedIncludeBodyReaderTag " + - "is not enclosed within an IncludeTag."; - log(msg); - throw new JspException(msg); - } - */ - - /** - * This method cleans up the member variables for this tag in preparation - * for being used again. This method is called when the tag finishes it's - * current call with in the page but could be called upon again within this - * same page. This method is also called in the release stage of the tag - * life cycle just in case a JspException was thrown during the tag - * execution. - */ - protected void clearServiceState() { - parameterName = null; - } - - /** - * This is the method responsible for taking the result of the JSP code - * that forms the body of this tag and inserts it as a parameter into the - * request scope session. If any problems occur while loading the body - * into the session scope then a {@code JspException} will be thrown. - * - * @param pContent The body of the tag as a String. - * @throws JspException - */ - protected void processBody(String pContent) throws JspException { - // Okay, we have the content, we need to write it to disk somewhere - String content = pContent; - - if (!StringUtil.isEmpty(language)) { - content = "<%@page language=\"" + language + "\" %>" + content; - } - - if (!StringUtil.isEmpty(prefix)) { - content = "<%@taglib uri=\"/twelvemonkeys-common\" prefix=\"" + prefix + "\" %>" + content; - } - - // Write the content of the oparam to disk - try { - log("Processing subpage " + subpage.getPath()); - FileUtil.write(subpage, content.getBytes()); - } - catch (IOException ioe) { - throw new JspException(ioe); - } - } - - /** Creates a unique filename for each (nested) oparam */ - private File createFileNameFromRequest(HttpServletRequest pRequest) { - //System.out.println("ServletPath" + pRequest.getServletPath()); - String path = pRequest.getServletPath(); - - // Find last '/' - int splitIndex = path.lastIndexOf("/"); - - // Split -> path + name - String name = path.substring(splitIndex + 1); - path = path.substring(0, splitIndex); - - // Replace special chars in name with '_' - name = name.replace('.', '_'); - String param = parameterName.replace('.', '_'); - param = param.replace('/', '_'); - param = param.replace('\\', '_'); - param = param.replace(':', '_'); - - // tempfile = realPath(path) + name + "_oparam_" + number + ".jsp" - int count = getOparamCountFromRequest(pRequest); - - // Hmm.. Would be great, but seems like I can't serve pages from within the temp dir - //File temp = (File) getServletContext().getAttribute("javax.servlet.context.tempdir"); - //return new File(new File(temp, path), name + "_oparam_" + count + "_" + param + ".jsp"); - - return new File(new File(pageContext.getServletContext().getRealPath(path)), name + "_oparam_" + count + "_" + param + ".jsp"); - } - - /** Gets the current oparam count for this request */ - private int getOparamCountFromRequest(HttpServletRequest pRequest) { - // Use request.attribute for incrementing oparam counter - Integer count = (Integer) pRequest.getAttribute(COUNTER); - if (count == null) { - count = new Integer(0); - } - else { - count = new Integer(count.intValue() + 1); - } - - // ... and set it back - pRequest.setAttribute(COUNTER, count); - - return count.intValue(); - } -} diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/ParamTag.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/ParamTag.java deleted file mode 100755 index fbe11574..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/ParamTag.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2002 TwelveMonkeys. - * All rights reserved. - * - * $Log: ParamTag.java,v $ - * Revision 1.2 2003/10/06 14:26:00 WMHAKUR - * Code clean-up only. - * - * Revision 1.1 2002/10/18 14:03:09 WMHAKUR - * Moved to com.twelvemonkeys.servlet.jsp.droplet.taglib - * - * - */ - -package com.twelvemonkeys.servlet.jsp.droplet.taglib; - -import com.twelvemonkeys.servlet.jsp.droplet.Param; -import com.twelvemonkeys.servlet.jsp.taglib.ExTagSupport; - -import javax.servlet.jsp.JspException; - -/** - * Parameter tag that emulates ATG Dynamo JHTML behaviour for JSP. - * - * @author Thomas Purcell (CSC Australia) - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * - * @version $Revision: #1 $, ($Date: 2008/05/05 $) - * - */ -public class ParamTag extends ExTagSupport { - - /** - * This is the name of the parameter to be inserted into the {@code - * PageContext.REQUEST_SCOPE} scope. - */ - private String parameterName; - - /** - * This is the value for the parameter to be inserted into the {@code - * PageContext.REQUEST_SCOPE} scope. - */ - private Object parameterValue; - - /** - * This method allows the JSP page to set the name for the parameter by - * using the {@code name} tag attribute. - * - * @param pName The name for the parameter to insert into the {@code - * PageContext.REQUEST_SCOPE} scope. - */ - public void setName(String pName) { - parameterName = pName; - } - - /** - * This method allows the JSP page to set the value for hte parameter by - * using the {@code value} tag attribute. - * - * @param pValue The value for the parameter to insert into the - * PageContext.REQUEST_SCOPE scope. - */ - public void setValue(String pValue) { - parameterValue = new Param(pValue); - } - - /** - * Ensure that the tag implemented by this class is enclosed by an {@code - * IncludeTag}. If the tag is not enclosed by an - * {@code IncludeTag} then a {@code JspException} is thrown. - * - * @return If this tag is enclosed within an {@code IncludeTag}, then - * the default return value from this method is the {@code - * TagSupport.SKIP_BODY} value. - * @exception JspException - */ - public int doStartTag() throws JspException { - //checkEnclosedInIncludeTag(); - - addParameter(); - - return SKIP_BODY; - } - - /** - * This is the method responsible for actually testing that the tag - * implemented by this class is enclosed within an {@code IncludeTag}. - * - * @exception JspException - */ - /* - protected void checkEnclosedInIncludeTag() throws JspException { - Tag parentTag = getParent(); - - if ((parentTag != null) && (parentTag instanceof IncludeTag)) { - return; - } - - String msg = "A class that extends EnclosedIncludeBodyReaderTag " + - "is not enclosed within an IncludeTag."; - log(msg); - throw new JspException(msg); - } - */ - - /** - * This method adds the parameter whose name and value were passed to this - * object via the tag attributes to the parent {@code Include} tag. - */ - private void addParameter() { - IncludeTag includeTag = (IncludeTag) getParent(); - - includeTag.addParameter(parameterName, parameterValue); - } - - /** - * This method cleans up the member variables for this tag in preparation - * for being used again. This method is called when the tag finishes it's - * current call with in the page but could be called upon again within this - * same page. This method is also called in the release stage of the tag - * life cycle just in case a JspException was thrown during the tag - * execution. - */ - protected void clearServiceState() { - parameterName = null; - parameterValue = null; - } -} diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/ValueOfTEI.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/ValueOfTEI.java deleted file mode 100755 index 692001bc..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/ValueOfTEI.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2002 TwelveMonkeys. - * All rights reserved. - * - * $Log: ValueOfTEI.java,v $ - * Revision 1.3 2003/10/06 14:26:07 WMHAKUR - * Code clean-up only. - * - * Revision 1.2 2002/10/18 14:28:07 WMHAKUR - * Fixed package error. - * - * Revision 1.1 2002/10/18 14:03:52 WMHAKUR - * Moved to com.twelvemonkeys.servlet.jsp.droplet.taglib - * - * - */ - -package com.twelvemonkeys.servlet.jsp.droplet.taglib; - -import javax.servlet.jsp.tagext.TagData; -import javax.servlet.jsp.tagext.TagExtraInfo; - -/** - * TagExtraInfo for ValueOf. - * @todo More meaningful response to the user. - * - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * - * @version $Revision: #1 $, ($Date: 2008/05/05 $) - * - */ - -public class ValueOfTEI extends TagExtraInfo { - - public boolean isValid(TagData pTagData) { - Object nameAttr = pTagData.getAttribute("name"); - Object paramAttr = pTagData.getAttribute("param"); - - if ((nameAttr != null && paramAttr == null) || (nameAttr == null && paramAttr != null)) { - return true; // Exactly one of name or param set - } - - // Either both or none, - return false; - } -} diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/ValueOfTag.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/ValueOfTag.java deleted file mode 100755 index a7e2a866..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/ValueOfTag.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2002 TwelveMonkeys. - * All rights reserved. - * - * $Log: ValueOfTag.java,v $ - * Revision 1.2 2003/10/06 14:26:14 WMHAKUR - * Code clean-up only. - * - * Revision 1.1 2002/10/18 14:03:52 WMHAKUR - * Moved to com.twelvemonkeys.servlet.jsp.droplet.taglib - * - * - */ - -package com.twelvemonkeys.servlet.jsp.droplet.taglib; - -import com.twelvemonkeys.servlet.jsp.droplet.JspFragment; -import com.twelvemonkeys.servlet.jsp.taglib.ExTagSupport; - -import javax.servlet.ServletException; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.JspWriter; -import javax.servlet.jsp.PageContext; -import java.io.IOException; - -/** - * ValueOf tag that emulates ATG Dynamo JHTML behaviour for JSP. - * - * @author Thomas Purcell (CSC Australia) - * @author Harald Kuhr - * @author last modified by $Author: haku $ - * - * @version $Revision: #1 $, ($Date: 2008/05/05 $) - */ -public class ValueOfTag extends ExTagSupport { - - /** - * This is the name of the parameter whose value is to be inserted into - * the current JSP page. This value will be set via the {@code name} - * attribute. - */ - private String parameterName; - - /** - * This is the value of the parameter read from the {@code - * PageContext.REQUEST_SCOPE} scope. If the parameter doesn't exist, - * then this will be null. - */ - private Object parameterValue; - - /** - * This method is called as part of the initialisation phase of the tag - * life cycle. It sets the parameter name to be read from the {@code - * PageContext.REQUEST_SCOPE} scope. - * - * @param pName The name of the parameter to be read from the {@code - * PageContext.REQUEST_SCOPE} scope. - */ - public void setName(String pName) { - parameterName = pName; - } - - /** - * This method is called as part of the initialisation phase of the tag - * life cycle. It sets the parameter name to be read from the {@code - * PageContext.REQUEST_SCOPE} scope. This is just a synonym for - * setName, to be more like ATG Dynamo. - * - * @param pName The name of the parameter to be read from the {@code - * PageContext.REQUEST_SCOPE} scope. - */ - public void setParam(String pName) { - parameterName = pName; - } - - /** - * This method looks in the session scope for the session-scoped attribute - * whose name matches the {@code name} tag attribute for this tag. - * If it finds it, then it replaces this tag with the value for the - * session-scoped attribute. If it fails to find the session-scoped - * attribute, it displays the body for this tag. - * - * @return If the session-scoped attribute is found, then this method will - * return {@code TagSupport.SKIP_BODY}, otherwise it will return - * {@code TagSupport.EVAL_BODY_INCLUDE}. - * @exception JspException - * - */ - public int doStartTag() throws JspException { - try { - if (parameterExists()) { - if (parameterValue instanceof JspFragment) { - // OPARAM or PARAM - ((JspFragment) parameterValue).service(pageContext); - /* - log("Service subpage " + pageContext.getServletContext().getRealPath(((Oparam) parameterValue).getName())); - - pageContext.include(((Oparam) parameterValue).getName()); - */ - } - else { - // Normal JSP parameter value - JspWriter writer = pageContext.getOut(); - writer.print(parameterValue); - } - - return SKIP_BODY; - } - else { - return EVAL_BODY_INCLUDE; - } - } - catch (ServletException se) { - log(se.getMessage(), se); - throw new JspException(se); - } - catch (IOException ioe) { - String msg = "Caught an IOException in ValueOfTag.doStartTag()\n" - + ioe.toString(); - log(msg, ioe); - throw new JspException(msg); - } - } - - /** - * This method is used to determine whether the parameter whose name is - * stored in {@code mParameterName} exists within the {@code - * PageContext.REQUEST_SCOPE} scope. If the parameter does exist, - * then this method will return {@code true}, otherwise it returns - * {@code false}. This method has the side affect of loading the - * parameter value into {@code mParameterValue} if the parameter - * does exist. - * - * @return {@code true} if the parameter whose name is in {@code - * mParameterName} exists in the {@code PageContext.REQUEST_SCOPE - * } scope, {@code false} otherwise. - */ - private boolean parameterExists() { - parameterValue = pageContext.getAttribute(parameterName, PageContext.REQUEST_SCOPE); - - // -- Harald K 20020726 - if (parameterValue == null) { - parameterValue = pageContext.getRequest().getParameter(parameterName); - } - - return (parameterValue != null); - } -} diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/package-info.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/package-info.java deleted file mode 100644 index 4aac8ff7..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/droplet/taglib/package-info.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2011, Harald Kuhr - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name "TwelveMonkeys" nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Dynamo Droplet-like functionality for JSP. - * - * This package is early beta, not for commercial use! :-) - * Read: The interfaces and classes in this package (and subpackages) will be - * developed and modified for a while. - * - * TODO: Insert taglib-descriptor here? - */ -package com.twelvemonkeys.servlet.jsp.droplet.taglib; \ No newline at end of file diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/package-info.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/package-info.java deleted file mode 100644 index 6681cfbc..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * JSP support. - */ -package com.twelvemonkeys.servlet.jsp; \ No newline at end of file diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/BodyReaderTag.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/BodyReaderTag.java deleted file mode 100755 index 60ea0a91..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/BodyReaderTag.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.twelvemonkeys.servlet.jsp.taglib; - -import javax.servlet.jsp.JspException; - -/** - * - * - * @author Thomas Purcell (CSC Australia) - * - * @version 1.0 - */ -public abstract class BodyReaderTag extends ExBodyTagSupport { - /** - * This is the method called by the JSP engine when the body for a tag - * has been parsed and is ready for inclusion in this current tag. This - * method takes the content as a string and passes it to the {@code - * processBody} method. - * - * @return This method returns the {@code BodyTagSupport.SKIP_BODY} - * constant. This means that the body of the tag will only be - * processed the one time. - * @exception JspException - */ - public int doAfterBody() throws JspException { - processBody(bodyContent.getString()); - return SKIP_BODY; - } - - /** - * This is the method that child classes must implement. It takes the - * body of the tag converted to a String as it's parameter. The body of - * the tag will have been interpreted to a String by the JSP engine before - * this method is called. - * - * @param pContent The body for the custom tag converted to a String. - * @exception JspException - */ - protected abstract void processBody(String pContent) throws JspException; -} diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/CSVToTableTag.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/CSVToTableTag.java deleted file mode 100755 index 9db7b6be..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/CSVToTableTag.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (c) 2002 TwelveMonkeys. - * All rights reserved. - * - * $Log: CSVToTableTag.java,v $ - * Revision 1.3 2003/10/06 14:24:50 WMHAKUR - * Code clean-up only. - * - * Revision 1.2 2002/11/26 17:33:49 WMHAKUR - * Added documentation & removed System.out.println()s. - * - * Revision 1.1 2002/11/19 10:50:10 WMHAKUR - * Renamed from CSVToTable, to follow naming conventions. - * - * Revision 1.1 2002/11/18 22:11:16 WMHAKUR - * Tag to convert CSV to HTML table. - * Can be further transformed, using XSLT. - * - */ - -package com.twelvemonkeys.servlet.jsp.taglib; - -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.JspWriter; -import javax.servlet.jsp.tagext.BodyContent; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.Reader; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.StringTokenizer; - -/** - * Creates a table from a string of "comma-separated values" (CSV). - * The delimiter character can be any character (or combination of characters). - * The default delimiter is TAB ({@code \t}). - * - *

- *


- *

- * - * The input may look like this: - *

- * <c:totable firstRowIsHeader="true" delimiter=";">
- *   header A;header B
- *   data 1A; data 1B
- *   data 2A; data 2B
- * </c:totable>
- * 
- * - * The output (source) will look like this: - *
- * <TABLE>
- *   <TR>
- *      <TH>header A</TH><TH>header B</TH>
- *   </TR>
- *   <TR>
- *      <TD>data 1A</TD><TD>data 1B</TD>
- *   </TR>
- *   <TR>
- *      <TD>data 2A</TD><TD>data 2B</TD>
- *   </TR>
- * </TABLE>
- * 
- * You wil probably want to use XSLT to make the final output look nicer. :-) - * - * @see StringTokenizer - * @see XSLT spec - * - * @author Harald Kuhr - * - * @version $Id: jsp/taglib/CSVToTableTag.java#1 $ - */ -public class CSVToTableTag extends ExBodyTagSupport { - public final static String TAB = "\t"; - - protected String delimiter = null; - protected boolean firstRowIsHeader = false; - protected boolean firstColIsHeader = false; - - public void setDelimiter(String pDelimiter) { - delimiter = pDelimiter; - } - - public String getDelimiter() { - return delimiter != null ? delimiter : TAB; - } - - public void setFirstRowIsHeader(String pBoolean) { - firstRowIsHeader = Boolean.valueOf(pBoolean); - } - - public void setFirstColIsHeader(String pBoolean) { - firstColIsHeader = Boolean.valueOf(pBoolean); - } - - - public int doEndTag() throws JspException { - BodyContent content = getBodyContent(); - - try { - Table table = - Table.parseContent(content.getReader(), getDelimiter()); - - JspWriter out = pageContext.getOut(); - - //System.out.println("CSVToTable: " + table.getRows() + " rows, " - // + table.getCols() + " cols."); - - if (table.getRows() > 0) { - out.println(""); - // Loop over rows - for (int row = 0; row < table.getRows(); row++) { - out.println(""); - - // Loop over cells in each row - for (int col = 0; col < table.getCols(); col++) { - // Test if we are using headers, else normal cell - if (firstRowIsHeader && row == 0 || firstColIsHeader && col == 0) { - out.println(""); - } - else { - out.println(""); - } - } - - out.println(""); - - } - out.println("
" + table.get(row, col) + " " + table.get(row, col) + "
"); - } - } - catch (IOException ioe) { - throw new JspException(ioe); - } - - return super.doEndTag(); - } - - static class Table { - List rows = null; - int cols = 0; - - private Table(List pRows, int pCols) { - rows = pRows; - cols = pCols; - } - - int getRows() { - return rows != null ? rows.size() : 0; - } - - int getCols() { - return cols; - } - - List getTableRows() { - return rows; - } - - List getTableRow(int pRow) { - return rows != null - ? (List) rows.get(pRow) - : Collections.EMPTY_LIST; - } - - String get(int pRow, int pCol) { - List row = getTableRow(pRow); - // Rows may contain unequal number of cols - return (row.size() > pCol) ? (String) row.get(pCol) : ""; - } - - /** - * Parses a BodyContent to a table. - * - */ - static Table parseContent(Reader pContent, String pDelim) throws IOException { - List> tableRows = new ArrayList>(); - int tdsPerTR = 0; - - // Loop through TRs - BufferedReader reader = new BufferedReader(pContent); - String tr; - while ((tr = reader.readLine()) != null) { - // Discard blank lines - if (tr.trim().length() <= 0 && tr.indexOf(pDelim) < 0) { - continue; - } - - //System.out.println("CSVToTable: read LINE=\"" + tr + "\""); - - List tableDatas = new ArrayList(); - StringTokenizer tableRow = new StringTokenizer(tr, pDelim, - true); - - boolean lastWasDelim = false; - while (tableRow.hasMoreTokens()) { - String td = tableRow.nextToken(); - - //System.out.println("CSVToTable: read data=\"" + td + "\""); - - // Test if we have empty TD - if (td.equals(pDelim)) { - if (lastWasDelim) { - // Add empty TD - tableDatas.add(""); - } - - // We just read a delimitter - lastWasDelim = true; - } - else { - // No tab, normal data - lastWasDelim = false; - - // Add normal TD - tableDatas.add(td); - } - } // end while (tableRow.hasNext()) - - // Store max TD count - if (tableDatas.size() > tdsPerTR) { - tdsPerTR = tableDatas.size(); - } - - // Add a table row - tableRows.add(tableDatas); - } - - // Return TABLE - return new Table(tableRows, tdsPerTR); - } - } -} diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/ExBodyTagSupport.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/ExBodyTagSupport.java deleted file mode 100755 index 10381ded..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/ExBodyTagSupport.java +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright (c) 2002 TwelveMonkeys. - * All rights reserved. - * - * $Log: ExBodyTagSupport.java,v $ - * Revision 1.3 2003/10/06 14:24:57 WMHAKUR - * Code clean-up only. - * - * Revision 1.2 2002/11/18 22:10:27 WMHAKUR - * *** empty log message *** - * - * - */ - -package com.twelvemonkeys.servlet.jsp.taglib; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.JspWriter; -import javax.servlet.jsp.PageContext; -import javax.servlet.jsp.tagext.BodyTagSupport; -import java.io.IOException; -import java.io.InputStream; -import java.util.Enumeration; -import java.util.StringTokenizer; - -/** - * This is the class that should be extended by all jsp pages that do use their - * body. It contains a lot of helper methods for simplifying common tasks. - * - * @author Thomas Purcell (CSC Australia) - * @author Harald Kuhr - * - * @version $Id: jsp/taglib/ExBodyTagSupport.java#1 $ - */ - -public class ExBodyTagSupport extends BodyTagSupport implements ExTag { - /** - * writeHtml ensures that the text being outputted appears as it was - * entered. This prevents users from hacking the system by entering - * html or jsp code into an entry form where that value will be displayed - * later in the site. - * - * @param pOut The JspWriter to write the output to. - * @param pHtml The original html to filter and output to the user. - * @throws IOException If the user clicks Stop in the browser, or their - * browser crashes, then the JspWriter will throw an IOException when - * the jsp tries to write to it. - */ - - public void writeHtml(JspWriter pOut, String pHtml) throws IOException { - StringTokenizer parser = new StringTokenizer(pHtml, "<>&", true); - - while (parser.hasMoreTokens()) { - String token = parser.nextToken(); - - if (token.equals("<")) { - pOut.print("<"); - } - else if (token.equals(">")) { - pOut.print(">"); - } - else if (token.equals("&")) { - pOut.print("&"); - } - else { - pOut.print(token); - } - } - } - - /** - * Log a message to the servlet context. - * - * @param pMsg The error message to log. - */ - - public void log(String pMsg) { - getServletContext().log(pMsg); - } - - /** - * Log a message to the servlet context and include the exception that is - * passed in as the second parameter. - * - * @param pMsg The error message to log. - * @param pException The exception that caused this error message to be - * logged. - */ - - public void log(String pMsg, Throwable pException) { - getServletContext().log(pMsg, pException); - } - - /** - * Retrieves the ServletContext object associated with the current - * PageContext object. - * - * @return The ServletContext object associated with the current - * PageContext object. - */ - - public ServletContext getServletContext() { - return pageContext.getServletContext(); - } - - /** - * Called when the tag has finished running. Any clean up that needs - * to be done between calls to this tag but within the same JSP page is - * called in the {@code clearServiceState()} method call. - * - * @exception JspException - */ - - public int doEndTag() throws JspException { - clearServiceState(); - return super.doEndTag(); - } - - /** - * Called when a tag's role in the current JSP page is finished. After - * the {@code clearProperties()} method is called, the custom tag - * should be in an identical state as when it was first created. The - * {@code clearServiceState()} method is called here just in case an - * exception was thrown in the custom tag. If an exception was thrown, - * then the {@code doEndTag()} method will not have been called and - * the tag might not have been cleaned up properly. - */ - - public void release() { - clearServiceState(); - - clearProperties(); - super.release(); - } - - /** - * The default implementation for the {@code clearProperties()}. Not - * all tags will need to overload this method call. By implementing it - * here, all classes that extend this object are able to call {@code - * super.clearProperties()}. So, if the class extends a different - * tag, or this one, the parent method should always be called. This - * method will be called when the tag is to be released. That is, the - * tag has finished for the current page and should be returned to it's - * initial state. - */ - - protected void clearProperties() { - } - - /** - * The default implementation for the {@code clearServiceState()}. - * Not all tags will need to overload this method call. By implementing it - * here, all classes that extend this object are able to call {@code - * super.clearServiceState()}. So, if the class extends a different - * tag, or this one, the parent method should always be called. This - * method will be called when the tag has finished it's current tag - * within the page, but may be called upon again in this same JSP page. - */ - - protected void clearServiceState() { - } - - /** - * Returns the initialisation parameter from the {@code - * PageContext.APPLICATION_SCOPE} scope. These initialisation - * parameters are defined in the {@code web.xml} configuration file. - * - * @param pName The name of the initialisation parameter to return the - * value for. - * @return The value for the parameter whose name was passed in as a - * parameter. If the parameter does not exist, then {@code null} - * will be returned. - */ - - public String getInitParameter(String pName) { - return getInitParameter(pName, PageContext.APPLICATION_SCOPE); - } - - /** - * Returns an Enumeration containing all the names for all the - * initialisation parametes defined in the {@code - * PageContext.APPLICATION_SCOPE} scope. - * - * @return An {@code Enumeration} containing all the names for all the - * initialisation parameters. - */ - - public Enumeration getInitParameterNames() { - return getInitParameterNames(PageContext.APPLICATION_SCOPE); - } - - /** - * Returns the initialisation parameter from the scope specified with the - * name specified. - * - * @param pName The name of the initialisation parameter to return the - * value for. - * @param pScope The scope to search for the initialisation parameter - * within. - * @return The value of the parameter found. If no parameter with the - * name specified is found in the scope specified, then {@code null - * } is returned. - */ - - public String getInitParameter(String pName, int pScope) { - switch (pScope) { - case PageContext.PAGE_SCOPE: - return getServletConfig().getInitParameter(pName); - case PageContext.APPLICATION_SCOPE: - return getServletContext().getInitParameter(pName); - default: - throw new IllegalArgumentException("Illegal scope."); - } - } - - /** - * Returns an enumeration containing all the parameters defined in the - * scope specified by the parameter. - * - * @param pScope The scope to return the names of all the parameters - * defined within. - * @return An {@code Enumeration} containing all the names for all the - * parameters defined in the scope passed in as a parameter. - */ - - public Enumeration getInitParameterNames(int pScope) { - switch (pScope) { - case PageContext.PAGE_SCOPE: - return getServletConfig().getInitParameterNames(); - case PageContext.APPLICATION_SCOPE: - return getServletContext().getInitParameterNames(); - default: - throw new IllegalArgumentException("Illegal scope"); - } - } - - /** - * Returns the servlet config associated with the current JSP page request. - * - * @return The {@code ServletConfig} associated with the current - * request. - */ - - public ServletConfig getServletConfig() { - return pageContext.getServletConfig(); - } - - /** - * Gets the context path associated with the current JSP page request. - * If the request is not a HttpServletRequest, this method will - * return "/". - * - * @return a path relative to the current context's root, or - * {@code "/"} if this is not a HTTP request. - */ - - public String getContextPath() { - ServletRequest request = pageContext.getRequest(); - if (request instanceof HttpServletRequest) { - return ((HttpServletRequest) request).getContextPath(); - } - return "/"; - } - - /** - * Gets the resource associated with the given relative path for the - * current JSP page request. - * The path may be absolute, or relative to the current context root. - * - * @param pPath the path - * - * @return a path relative to the current context root - */ - - public InputStream getResourceAsStream(String pPath) { - // throws MalformedURLException { - String path = pPath; - - if (pPath != null && !pPath.startsWith("/")) { - path = getContextPath() + pPath; - } - - return pageContext.getServletContext().getResourceAsStream(path); - } - -} diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/ExTag.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/ExTag.java deleted file mode 100755 index e0817362..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/ExTag.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2002 TwelveMonkeys. - * All rights reserved. - * - * $Log: ExTag.java,v $ - * Revision 1.2 2003/10/06 14:25:05 WMHAKUR - * Code clean-up only. - * - * Revision 1.1 2002/11/18 22:10:27 WMHAKUR - * *** empty log message *** - * - * - */ - -package com.twelvemonkeys.servlet.jsp.taglib; - - -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.jsp.JspWriter; -import javax.servlet.jsp.tagext.Tag; -import java.io.IOException; -import java.io.InputStream; -import java.util.Enumeration; - -/** - * This interface contains a lot of helper methods for simplifying common - * taglib related tasks. - * - * @author Harald Kuhr - * - * @version $Id: jsp/taglib/ExTag.java#1 $ - */ - -public interface ExTag extends Tag { - - /** - * writeHtml ensures that the text being outputted appears as it was - * entered. This prevents users from hacking the system by entering - * html or jsp code into an entry form where that value will be displayed - * later in the site. - * - * @param pOut The JspWriter to write the output to. - * @param pHtml The original html to filter and output to the user. - * @throws IOException If the user clicks Stop in the browser, or their - * browser crashes, then the JspWriter will throw an IOException when - * the jsp tries to write to it. - */ - - public void writeHtml(JspWriter pOut, String pHtml) throws IOException; - - /** - * Log a message to the servlet context. - * - * @param pMsg The error message to log. - */ - - public void log(String pMsg); - - /** - * Logs a message to the servlet context and include the exception that is - * passed in as the second parameter. - * - * @param pMsg The error message to log. - * @param pException The exception that caused this error message to be - * logged. - */ - - public void log(String pMsg, Throwable pException); - - /** - * Retrieves the ServletContext object associated with the current - * PageContext object. - * - * @return The ServletContext object associated with the current - * PageContext object. - */ - - public ServletContext getServletContext(); - - /** - * Returns the initialisation parameter from the {@code - * PageContext.APPLICATION_SCOPE} scope. These initialisation - * parameters are defined in the {@code web.xml} configuration file. - * - * @param pName The name of the initialisation parameter to return the - * value for. - * @return The value for the parameter whose name was passed in as a - * parameter. If the parameter does not exist, then {@code null} - * will be returned. - */ - - public String getInitParameter(String pName); - - /** - * Returns an Enumeration containing all the names for all the - * initialisation parametes defined in the {@code - * PageContext.APPLICATION_SCOPE} scope. - * - * @return An {@code Enumeration} containing all the names for all the - * initialisation parameters. - */ - - public Enumeration getInitParameterNames(); - - /** - * Returns the initialisation parameter from the scope specified with the - * name specified. - * - * @param pName The name of the initialisation parameter to return the - * value for. - * @param pScope The scope to search for the initialisation parameter - * within. - * @return The value of the parameter found. If no parameter with the - * name specified is found in the scope specified, then {@code null - * } is returned. - */ - - public String getInitParameter(String pName, int pScope); - - /** - * Returns an enumeration containing all the parameters defined in the - * scope specified by the parameter. - * - * @param pScope The scope to return the names of all the parameters - * defined within. - * @return An {@code Enumeration} containing all the names for all the - * parameters defined in the scope passed in as a parameter. - */ - - public Enumeration getInitParameterNames(int pScope); - - /** - * Returns the servlet config associated with the current JSP page request. - * - * @return The {@code ServletConfig} associated with the current - * request. - */ - - public ServletConfig getServletConfig(); - - /** - * Gets the context path associated with the current JSP page request. - * - * @return a path relative to the current context's root. - */ - - public String getContextPath(); - - - /** - * Gets the resource associated with the given relative path for the - * current JSP page request. - * The path may be absolute, or relative to the current context root. - * - * @param pPath the path - * - * @return a path relative to the current context root - */ - - public InputStream getResourceAsStream(String pPath); - -} diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/ExTagSupport.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/ExTagSupport.java deleted file mode 100755 index 3391064e..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/ExTagSupport.java +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright (c) 2002 TwelveMonkeys. - * All rights reserved. - * - * $Log: ExTagSupport.java,v $ - * Revision 1.3 2003/10/06 14:25:11 WMHAKUR - * Code clean-up only. - * - * Revision 1.2 2002/11/18 22:10:27 WMHAKUR - * *** empty log message *** - * - * - */ - -package com.twelvemonkeys.servlet.jsp.taglib; - - -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.JspWriter; -import javax.servlet.jsp.PageContext; -import javax.servlet.jsp.tagext.TagSupport; -import java.io.IOException; -import java.io.InputStream; -import java.util.Enumeration; -import java.util.StringTokenizer; - -/** - * This is the class that should be extended by all jsp pages that don't use - * their body. It contains a lot of helper methods for simplifying common - * tasks. - * - * @author Thomas Purcell (CSC Australia) - * @author Harald Kuhr - * - * @version $Id: jsp/taglib/ExTagSupport.java#1 $ - */ - -public class ExTagSupport extends TagSupport implements ExTag { - /** - * writeHtml ensures that the text being outputted appears as it was - * entered. This prevents users from hacking the system by entering - * html or jsp code into an entry form where that value will be displayed - * later in the site. - * - * @param pOut The JspWriter to write the output to. - * @param pHtml The original html to filter and output to the user. - * @throws IOException If the user clicks Stop in the browser, or their - * browser crashes, then the JspWriter will throw an IOException when - * the jsp tries to write to it. - */ - - public void writeHtml(JspWriter pOut, String pHtml) throws IOException { - StringTokenizer parser = new StringTokenizer(pHtml, "<>&", true); - - while (parser.hasMoreTokens()) { - String token = parser.nextToken(); - - if (token.equals("<")) { - pOut.print("<"); - } - else if (token.equals(">")) { - pOut.print(">"); - } - else if (token.equals("&")) { - pOut.print("&"); - } - else { - pOut.print(token); - } - } - } - - /** - * Log a message to the servlet context. - * - * @param pMsg The error message to log. - */ - - public void log(String pMsg) { - getServletContext().log(pMsg); - } - - /** - * Log a message to the servlet context and include the exception that is - * passed in as the second parameter. - * - * @param pMsg The error message to log. - * @param pException The exception that caused this error message to be - * logged. - */ - - public void log(String pMsg, Throwable pException) { - getServletContext().log(pMsg, pException); - } - - /** - * Retrieves the ServletContext object associated with the current - * PageContext object. - * - * @return The ServletContext object associated with the current - * PageContext object. - */ - - public ServletContext getServletContext() { - return pageContext.getServletContext(); - } - - /** - * Called when the tag has finished running. Any clean up that needs - * to be done between calls to this tag but within the same JSP page is - * called in the {@code clearServiceState()} method call. - * - * @exception JspException - */ - - public int doEndTag() throws JspException { - clearServiceState(); - return super.doEndTag(); - } - - /** - * Called when a tag's role in the current JSP page is finished. After - * the {@code clearProperties()} method is called, the custom tag - * should be in an identical state as when it was first created. The - * {@code clearServiceState()} method is called here just in case an - * exception was thrown in the custom tag. If an exception was thrown, - * then the {@code doEndTag()} method will not have been called and - * the tag might not have been cleaned up properly. - */ - - public void release() { - clearServiceState(); - - clearProperties(); - super.release(); - } - - /** - * The default implementation for the {@code clearProperties()}. Not - * all tags will need to overload this method call. By implementing it - * here, all classes that extend this object are able to call {@code - * super.clearProperties()}. So, if the class extends a different - * tag, or this one, the parent method should always be called. This - * method will be called when the tag is to be released. That is, the - * tag has finished for the current page and should be returned to it's - * initial state. - */ - - protected void clearProperties() { - } - - /** - * The default implementation for the {@code clearServiceState()}. - * Not all tags will need to overload this method call. By implementing it - * here, all classes that extend this object are able to call {@code - * super.clearServiceState()}. So, if the class extends a different - * tag, or this one, the parent method should always be called. This - * method will be called when the tag has finished it's current tag - * within the page, but may be called upon again in this same JSP page. - */ - - protected void clearServiceState() { - } - - /** - * Returns the initialisation parameter from the {@code - * PageContext.APPLICATION_SCOPE} scope. These initialisation - * parameters are defined in the {@code web.xml} configuration file. - * - * @param pName The name of the initialisation parameter to return the - * value for. - * @return The value for the parameter whose name was passed in as a - * parameter. If the parameter does not exist, then {@code null} - * will be returned. - */ - - public String getInitParameter(String pName) { - return getInitParameter(pName, PageContext.APPLICATION_SCOPE); - } - - /** - * Returns an Enumeration containing all the names for all the - * initialisation parametes defined in the {@code - * PageContext.APPLICATION_SCOPE} scope. - * - * @return An {@code Enumeration} containing all the names for all the - * initialisation parameters. - */ - - public Enumeration getInitParameterNames() { - return getInitParameterNames(PageContext.APPLICATION_SCOPE); - } - - /** - * Returns the initialisation parameter from the scope specified with the - * name specified. - * - * @param pName The name of the initialisation parameter to return the - * value for. - * @param pScope The scope to search for the initialisation parameter - * within. - * @return The value of the parameter found. If no parameter with the - * name specified is found in the scope specified, then {@code null - * } is returned. - */ - - public String getInitParameter(String pName, int pScope) { - switch (pScope) { - case PageContext.PAGE_SCOPE: - return getServletConfig().getInitParameter(pName); - case PageContext.APPLICATION_SCOPE: - return getServletContext().getInitParameter(pName); - default: - throw new IllegalArgumentException("Illegal scope."); - } - } - - /** - * Returns an enumeration containing all the parameters defined in the - * scope specified by the parameter. - * - * @param pScope The scope to return the names of all the parameters - * defined within. - * @return An {@code Enumeration} containing all the names for all the - * parameters defined in the scope passed in as a parameter. - */ - - public Enumeration getInitParameterNames(int pScope) { - switch (pScope) { - case PageContext.PAGE_SCOPE: - return getServletConfig().getInitParameterNames(); - case PageContext.APPLICATION_SCOPE: - return getServletContext().getInitParameterNames(); - default: - throw new IllegalArgumentException("Illegal scope"); - } - } - - /** - * Returns the servlet config associated with the current JSP page request. - * - * @return The {@code ServletConfig} associated with the current - * request. - */ - - public ServletConfig getServletConfig() { - return pageContext.getServletConfig(); - } - - /** - * Gets the context path associated with the current JSP page request. - * If the request is not a HttpServletRequest, this method will - * return "/". - * - * @return a path relative to the current context's root, or - * {@code "/"} if this is not a HTTP request. - */ - - public String getContextPath() { - ServletRequest request = pageContext.getRequest(); - if (request instanceof HttpServletRequest) { - return ((HttpServletRequest) request).getContextPath(); - } - return "/"; - } - - /** - * Gets the resource associated with the given relative path for the - * current JSP page request. - * The path may be absolute, or relative to the current context root. - * - * @param pPath the path - * - * @return a path relative to the current context root - */ - - public InputStream getResourceAsStream(String pPath) { - //throws MalformedURLException { - String path = pPath; - - if (pPath != null && !pPath.startsWith("/")) { - path = getContextPath() + pPath; - } - - return pageContext.getServletContext().getResourceAsStream(path); - } - - -} diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/LastModifiedTEI.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/LastModifiedTEI.java deleted file mode 100755 index 99c3e5fc..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/LastModifiedTEI.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.twelvemonkeys.servlet.jsp.taglib; - -import javax.servlet.jsp.*; -import javax.servlet.jsp.tagext.*; - -/** - * TagExtraInfo for LastModifiedTag - * - * @author Harald Kuhr - * - * @version 1.1 - */ - -public class LastModifiedTEI extends TagExtraInfo { - public VariableInfo[] getVariableInfo(TagData pData) { - return new VariableInfo[]{ - new VariableInfo("lastModified", "java.lang.String", true, VariableInfo.NESTED), - }; - } -} diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/LastModifiedTag.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/LastModifiedTag.java deleted file mode 100755 index 7c8da4b3..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/LastModifiedTag.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.twelvemonkeys.servlet.jsp.taglib; - -import com.twelvemonkeys.util.convert.Converter; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.tagext.Tag; -import javax.servlet.jsp.tagext.TagSupport; -import java.io.File; -import java.util.Date; - -/** - * Prints the last modified - */ - -public class LastModifiedTag extends TagSupport { - private String fileName = null; - private String format = null; - - public void setFile(String pFileName) { - fileName = pFileName; - } - - public void setFormat(String pFormat) { - format = pFormat; - } - - public int doStartTag() throws JspException { - File file; - - if (fileName != null) { - file = new File(pageContext.getServletContext().getRealPath(fileName)); - } - else { - HttpServletRequest request = (HttpServletRequest) pageContext.getRequest(); - - // Get the file containing the servlet - file = new File(pageContext.getServletContext().getRealPath(request.getServletPath())); - } - - Date lastModified = new Date(file.lastModified()); - Converter conv = Converter.getInstance(); - - // Set the last modified value back - pageContext.setAttribute("lastModified", conv.toString(lastModified, format)); - - return Tag.EVAL_BODY_INCLUDE; - } -} diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/TrimWhiteSpaceTag.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/TrimWhiteSpaceTag.java deleted file mode 100755 index 38d47836..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/TrimWhiteSpaceTag.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.twelvemonkeys.servlet.jsp.taglib; - -import java.io.IOException; - -import javax.servlet.jsp.JspException; - -/** - * This tag truncates all consecutive whitespace in sequence inside its body, - * to one whitespace character. The first whitespace character in the sequence - * will be left untouched (except for CR/LF, which will always leave a LF). - * - * @author Harald Kuhr - * - * @version 1.0 - */ - -public class TrimWhiteSpaceTag extends ExBodyTagSupport { - - /** - * doStartTag implementation, simply returns - * {@code BodyTag.EVAL_BODY_BUFFERED}. - * - * @return {@code BodyTag.EVAL_BODY_BUFFERED} - */ - - public int doStartTag() throws JspException { - return EVAL_BODY_BUFFERED; - } - - /** - * doEndTag implementation, truncates all whitespace. - * - * @return {@code super.doEndTag()} - */ - - public int doEndTag() throws JspException { - // Trim - String trimmed = truncateWS(bodyContent.getString()); - try { - // Print trimmed content - //pageContext.getOut().print("\n"); - pageContext.getOut().print(trimmed); - //pageContext.getOut().print("\n"); - } - catch (IOException ioe) { - throw new JspException(ioe); - } - - return super.doEndTag(); - } - - /** - * Truncates whitespace from the given string. - * - * @todo Candidate for StringUtil? - */ - - private static String truncateWS(String pStr) { - char[] chars = pStr.toCharArray(); - - int count = 0; - boolean lastWasWS = true; // Avoids leading WS - for (int i = 0; i < chars.length; i++) { - if (!Character.isWhitespace(chars[i])) { - // if char is not WS, just store - chars[count++] = chars[i]; - lastWasWS = false; - } - else { - // else, if char is WS, store first, skip the rest - if (!lastWasWS) { - if (chars[i] == 0x0d) { - chars[count++] = 0x0a; //Always new line - } - else { - chars[count++] = chars[i]; - } - } - lastWasWS = true; - } - } - - // Return the trucated string - return new String(chars, 0, count); - } - -} diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/XMLTransformTag.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/XMLTransformTag.java deleted file mode 100755 index 6e712544..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/XMLTransformTag.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2002 TwelveMonkeys. - * All rights reserved. - * - * $Log: XMLTransformTag.java,v $ - * Revision 1.2 2003/10/06 14:25:43 WMHAKUR - * Code clean-up only. - * - * Revision 1.1 2002/11/19 10:50:41 WMHAKUR - * *** empty log message *** - * - */ - -package com.twelvemonkeys.servlet.jsp.taglib; - -import java.io.*; -import java.net.*; - -import javax.servlet.jsp.*; -import javax.xml.transform.*; -import javax.xml.transform.stream.*; - -/** - * This tag performs XSL Transformations (XSLT) on a given XML document or its - * body content. - * - * @author Harald Kuhr - * - * @version $Id: jsp/taglib/XMLTransformTag.java#1 $ - */ - -public class XMLTransformTag extends ExBodyTagSupport { - private String mDocumentURI = null; - private String mStylesheetURI = null; - - /** - * Sets the document attribute for this tag. - */ - - public void setDocumentURI(String pDocumentURI) { - mDocumentURI = pDocumentURI; - } - - /** - * Sets the stylesheet attribute for this tag. - */ - - public void setStylesheetURI(String pStylesheetURI) { - mStylesheetURI = pStylesheetURI; - } - - - /** - * doStartTag implementation, that performs XML Transformation on the - * given document, if any. - * If the documentURI attribute is set, then the transformation is - * performed on the document at that location, and - * {@code Tag.SKIP_BODY} is returned. - * Otherwise, this method simply returns - * {@code BodyTag.EVAL_BODY_BUFFERED} and leaves the transformation to - * the doEndTag. - * - * @return {@code Tag.SKIP_BODY} if {@code documentURI} is not - * {@code null}, otherwise - * {@code BodyTag.EVAL_BODY_BUFFERED}. - * - * @todo Is it really a good idea to allow "inline" XML in a JSP? - */ - - public int doStartTag() throws JspException { - //log("XML: " + mDocumentURI + " XSL: " + mStylesheetURI); - - if (mDocumentURI != null) { - // If document given, transform and skip body... - try { - transform(getSource(mDocumentURI)); - } - catch (MalformedURLException murle) { - throw new JspException(murle.getMessage(), murle); - } - catch (IOException ioe) { - throw new JspException(ioe.getMessage(), ioe); - } - - return SKIP_BODY; - } - - // ...else process the body - return EVAL_BODY_BUFFERED; - } - - /** - * doEndTag implementation, that will perform XML Transformation on the - * body content. - * - * @return super.doEndTag() - */ - - public int doEndTag() throws JspException { - // Get body content (trim is CRUCIAL, as some XML parsers are picky...) - String body = bodyContent.getString().trim(); - - // Do transformation - transform(new StreamSource(new ByteArrayInputStream(body.getBytes()))); - - return super.doEndTag(); - } - - /** - * Performs the transformation and writes the result to the JSP writer. - * - * @param in the source document to transform. - */ - - public void transform(Source pIn) throws JspException { - try { - // Create transformer - Transformer transformer = TransformerFactory.newInstance() - .newTransformer(getSource(mStylesheetURI)); - - // Store temporary output in a bytearray, as the transformer will - // usually try to flush the stream (illegal operation from a custom - // tag). - ByteArrayOutputStream os = new ByteArrayOutputStream(); - StreamResult out = new StreamResult(os); - - // Perform the transformation - transformer.transform(pIn, out); - - // Write the result back to the JSP writer - pageContext.getOut().print(os.toString()); - } - catch (MalformedURLException murle) { - throw new JspException(murle.getMessage(), murle); - } - catch (IOException ioe) { - throw new JspException(ioe.getMessage(), ioe); - } - catch (TransformerException te) { - throw new JspException("XSLT Trandformation failed: " + te.getMessage(), te); - } - } - - /** - * Returns a StreamSource object, for the given URI - */ - - private StreamSource getSource(String pURI) - throws IOException, MalformedURLException { - if (pURI != null && pURI.indexOf("://") < 0) { - // If local, get as stream - return new StreamSource(getResourceAsStream(pURI)); - } - - // ...else, create from URI string - return new StreamSource(pURI); - } -} diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/logic/ConditionalTagBase.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/logic/ConditionalTagBase.java deleted file mode 100755 index 9a2bb605..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/logic/ConditionalTagBase.java +++ /dev/null @@ -1,138 +0,0 @@ -/**************************************************** - * * - * (c) 2000-2003 TwelveMonkeys * - * All rights reserved * - * http://www.twelvemonkeys.no * - * * - * $RCSfile: ConditionalTagBase.java,v $ - * @version $Revision: #1 $ - * $Date: 2008/05/05 $ - * * - * @author Last modified by: $Author: haku $ - * * - ****************************************************/ - - - -/* - * Produced (p) 2002 TwelveMonkeys - * Address : Svovelstikka 1, Box 6432 Etterstad, 0605 Oslo, Norway. - * Phone : +47 22 57 70 00 - * Fax : +47 22 57 70 70 - */ -package com.twelvemonkeys.servlet.jsp.taglib.logic; - - -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.tagext.TagSupport; - - -/** - *

An abstract base class for tags with some kind of conditional presentation of the tag body.

- * - * @version 1.0 - * @author Eirik Torske - */ -public abstract class ConditionalTagBase extends TagSupport { - - // Members - protected String objectName; - protected String objectValue; - - // Properties - - /** - * Method getName - * - * - * @return - * - */ - public String getName() { - return objectName; - } - - /** - * Method setName - * - * - * @param pObjectName - * - */ - public void setName(String pObjectName) { - this.objectName = pObjectName; - } - - /** - * Method getValue - * - * - * @return - * - */ - public String getValue() { - return objectValue; - } - - /** - * Method setValue - * - * - * @param pObjectValue - * - */ - public void setValue(String pObjectValue) { - this.objectValue = pObjectValue; - } - - /** - *

Perform the test required for this particular tag, and either evaluate or skip the body of this tag.

- * - * - * @return - * @exception JspException if a JSP exception occurs. - */ - public int doStartTag() throws JspException { - - if (condition()) { - return (EVAL_BODY_INCLUDE); - } else { - return (SKIP_BODY); - } - } - - /** - *

Evaluate the remainder of the current page as normal.

- * - * - * @return - * @exception JspException if a JSP exception occurs. - */ - public int doEndTag() throws JspException { - return (EVAL_PAGE); - } - - /** - *

Release all allocated resources.

- */ - public void release() { - - super.release(); - objectName = null; - objectValue = null; - } - - /** - *

The condition that must be met in order to display the body of this tag.

- * - * @exception JspException if a JSP exception occurs. - * @return {@code true} if and only if all conditions are met. - */ - protected abstract boolean condition() throws JspException; -} - - -/*--- Formatted in Sun Java Convention Style on ma, des 1, '03 ---*/ - - -/*------ Formatted by Jindent 3.23 Basic 1.0 --- http://www.jindent.de ------*/ diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/logic/EqualTag.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/logic/EqualTag.java deleted file mode 100755 index 8726bb8b..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/logic/EqualTag.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Produced (p) 2002 TwelveMonkeys - * Address : Svovelstikka 1, Box 6432 Etterstad, 0605 Oslo, Norway. - * Phone : +47 22 57 70 00 - * Fax : +47 22 57 70 70 - */ - -package com.twelvemonkeys.servlet.jsp.taglib.logic; - - -import com.twelvemonkeys.lang.StringUtil; - -import javax.servlet.http.Cookie; -import javax.servlet.jsp.JspException; - - -/** - *

- * Custom tag for testing equality of an attribute against a given value. - * The attribute types supported so far is: - *

    - *
  • {@code java.lang.String} (ver. 1.0) - *
  • {@code javax.servlet.http.Cookie} (ver. 1.0) - *
- *

- * See the implemented {@code condition} method for details regarding the equality conditions. - * - *


- * - *

Tag Reference

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
equalAvailability: 1.0

Tag for testing if an attribute is equal to a given value.

Tag BodyJSP    
Restrictions

None

AttributesNameRequiredRuntime Expression EvaluationAvailability
 name Yes Yes 1.0
 

The attribute name

 value No Yes 1.0
 

The value for equality testing

VariablesNone
Examples - *
- *<%@ taglib prefix="twelvemonkeys" uri="twelvemonkeys-logic" %>
- *<bean:cookie id="logonUsernameCookie"
- *    name="<%= com.strutscommand.Constants.LOGON_USERNAME_COOKIE_NAME %>"
- *    value="no_username_set" />
- *<twelvemonkeys:equal name="logonUsernameCookie" value="no_username_set">
- *    <html:text property="username" />
- *</twelvemonkeys:equal>
- *      
- *
- * - *
- * - * @version 1.0 - * @author Eirik Torske - * @see notEqual - */ -public class EqualTag extends ConditionalTagBase { - - /** - * - * - * The conditions that must be met in order to display the body of this tag: - *
    - *
  1. The attribute name property ({@code name} -> {@code mObjectName}) must not be empty. - *
  2. The attribute must exist. - *
  3. The attribute must be an instance of one of the supported classes: - *
      - *
    • {@code java.lang.String} - *
    • {@code javax.servlet.http.Cookie} - *
    - *
  4. The value of the attribute must be equal to the object value property ({@code value} -> {@code mObjectValue}). - *
- *

- * NB! If the object value property ({@code value} -> {@code mObjectValue}) is empty than {@code true} will be returned. - *

- * - * @return {@code true} if and only if all conditions are met. - */ - protected boolean condition() throws JspException { - - if (StringUtil.isEmpty(objectName)) { - return false; - } - - if (StringUtil.isEmpty(objectValue)) { - return true; - } - - Object pageScopedAttribute = pageContext.getAttribute(objectName); - if (pageScopedAttribute == null) { - return false; - } - - String pageScopedStringAttribute; - - // String - if (pageScopedAttribute instanceof String) { - pageScopedStringAttribute = (String) pageScopedAttribute; - - // Cookie - } - else if (pageScopedAttribute instanceof Cookie) { - pageScopedStringAttribute = ((Cookie) pageScopedAttribute).getValue(); - - // Type not yet supported... - } - else { - return false; - } - - return (pageScopedStringAttribute.equals(objectValue)); - } - -} diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/logic/IteratorProviderTEI.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/logic/IteratorProviderTEI.java deleted file mode 100755 index 1dcb412a..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/logic/IteratorProviderTEI.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.twelvemonkeys.servlet.jsp.taglib.logic; - -import javax.servlet.jsp.tagext.*; - -/** - * TagExtraInfo class for IteratorProvider tags. - * - * @author Harald Kuhr - * @version $id: $ - */ -public class IteratorProviderTEI extends TagExtraInfo { - /** - * Gets the variable info for IteratorProvider tags. The attribute with the - * name defined by the "id" attribute and type defined by the "type" - * attribute is declared with scope {@code VariableInfo.AT_END}. - * - * @param pData TagData instance provided by container - * @return an VariableInfo array of lenght 1, containing the attribute - * defined by the id parameter, declared, and with scope - * {@code VariableInfo.AT_END}. - */ - public VariableInfo[] getVariableInfo(TagData pData) { - // Get attribute name - String attributeName = pData.getId(); - if (attributeName == null) { - attributeName = IteratorProviderTag.getDefaultIteratorName(); - } - - // Get type - String type = pData.getAttributeString(IteratorProviderTag.ATTRIBUTE_TYPE); - if (type == null) { - type = IteratorProviderTag.getDefaultIteratorType(); - } - - // Return the variable info - return new VariableInfo[]{ - new VariableInfo(attributeName, type, true, VariableInfo.AT_END), - }; - } -} diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/logic/IteratorProviderTag.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/logic/IteratorProviderTag.java deleted file mode 100755 index 1fd61a1a..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/logic/IteratorProviderTag.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.twelvemonkeys.servlet.jsp.taglib.logic; - -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.tagext.Tag; -import javax.servlet.jsp.tagext.TagSupport; -import java.util.Iterator; - -/** - * Abstract base class for adding iterators to a page. - * - * @todo Possible to use same strategy for all types of objects? Rename class - * to ObjectProviderTag? Hmmm... Might work. - * - * @author Harald Kuhr - * @version $id: $ - */ -public abstract class IteratorProviderTag extends TagSupport { - /** {@code iterator} */ - protected final static String DEFAULT_ITERATOR_NAME = "iterator"; - /** {@code java.util.iterator} */ - protected final static String DEFAULT_ITERATOR_TYPE = "java.util.Iterator"; - /** {@code type} */ - public final static String ATTRIBUTE_TYPE = "type"; - - /** */ - private String type = null; - - /** - * Gets the type. - * - * @return the type (class name) - */ - public String getType() { - return type; - } - - /** - * Sets the type. - * - * @param pType - */ - - public void setType(String pType) { - type = pType; - } - - /** - * doEndTag implementation. - * - * @return {@code Tag.EVAL_PAGE} - * @throws JspException - */ - - public int doEndTag() throws JspException { - // Set the iterator - pageContext.setAttribute(getId(), getIterator()); - - return Tag.EVAL_PAGE; - } - - /** - * Gets the iterator for this tag. - * - * @return an {@link java.util.Iterator} - */ - protected abstract Iterator getIterator(); - - /** - * Gets the default iterator name. - * - * @return {@link #DEFAULT_ITERATOR_NAME} - */ - protected static String getDefaultIteratorName() { - return DEFAULT_ITERATOR_NAME; - } - - /** - * Gets the default iterator type. - * - * @return {@link #DEFAULT_ITERATOR_TYPE} - */ - protected static String getDefaultIteratorType() { - return DEFAULT_ITERATOR_TYPE; - } - -} diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/logic/NotEqualTag.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/logic/NotEqualTag.java deleted file mode 100755 index 72082b08..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/logic/NotEqualTag.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Produced (p) 2002 TwelveMonkeys - * Address : Svovelstikka 1, Box 6432 Etterstad, 0605 Oslo, Norway. - * Phone : +47 22 57 70 00 - * Fax : +47 22 57 70 70 - */ - -package com.twelvemonkeys.servlet.jsp.taglib.logic; - - -import com.twelvemonkeys.lang.StringUtil; - -import javax.servlet.http.Cookie; -import javax.servlet.jsp.JspException; - - -/** - *

- * Custom tag for testing non-equality of an attribute against a given value. - * The attribute types supported so far is: - *

    - *
  • {@code java.lang.String} (ver. 1.0) - *
  • {@code javax.servlet.http.Cookie} (ver. 1.0) - *
- *

- * See the implemented {@code condition} method for details regarding the non-equality conditions. - * - *


- * - *

Tag Reference

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
notEqualAvailability: 1.0

Tag for testing if an attribute is NOT equal to a given value.

Tag BodyJSP    
Restrictions

None

AttributesNameRequiredRuntime Expression EvaluationAvailability
 name Yes Yes 1.0
 

The attribute name

 value No Yes 1.0
 

The value for equality testing

VariablesNone
Examples - *
- *<%@ taglib prefix="twelvemonkeys" uri="twelvemonkeys-logic" %>
- *<bean:cookie id="logonUsernameCookie"
- *    name="<%= com.strutscommand.Constants.LOGON_USERNAME_COOKIE_NAME %>"
- *    value="no_username_set" />
- *<twelvemonkeys:notEqual name="logonUsernameCookie" value="no_username_set">
- *    <html:text property="username" value="<%= logonUsernameCookie.getValue() %>" />
- *</twelvemonkeys:notEqual>
- *      
- *
- * - *
- * - * @version 1.0 - * @author Eirik Torske - * @see equal - */ -public class NotEqualTag extends ConditionalTagBase { - - /** - * - * - * The condition that must be met in order to display the body of this tag: - *
    - *
  1. The attribute name property ({@code name} -> {@code mObjectName}) must not be empty. - *
  2. The attribute must exist. - *
  3. The attribute must be an instance of one of the supported classes: - *
      - *
    • {@code java.lang.String} - *
    • {@code javax.servlet.http.Cookie} - *
    - *
  4. The value of the attribute must NOT be equal to the object value property ({@code value} -> {@code mObjectValue}). - *
- *

- * NB! If the object value property ({@code value} -> {@code mObjectValue}) is empty than {@code true} will be returned. - *

- * - * @return {@code true} if and only if all conditions are met. - */ - protected boolean condition() throws JspException { - - if (StringUtil.isEmpty(objectName)) { - return false; - } - - if (StringUtil.isEmpty(objectValue)) { - return true; - } - - Object pageScopedAttribute = pageContext.getAttribute(objectName); - if (pageScopedAttribute == null) { - return false; - } - - String pageScopedStringAttribute; - - // String - if (pageScopedAttribute instanceof String) { - pageScopedStringAttribute = (String) pageScopedAttribute; - - // Cookie - } - else if (pageScopedAttribute instanceof Cookie) { - pageScopedStringAttribute = ((Cookie) pageScopedAttribute).getValue(); - - // Type not yet supported... - } - else { - return false; - } - - return (!(pageScopedStringAttribute.equals(objectValue))); - } - -} diff --git a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/package-info.java b/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/package-info.java deleted file mode 100644 index 750d7abf..00000000 --- a/sandbox/sandbox-servlet/src/main/java/com/twelvemonkeys/servlet/jsp/taglib/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * The TwelveMonkeys common TagLib. - */ -package com.twelvemonkeys.servlet.jsp.taglib; diff --git a/sandbox/sandbox-swing/pom.xml b/sandbox/sandbox-swing/pom.xml deleted file mode 100644 index c6d57072..00000000 --- a/sandbox/sandbox-swing/pom.xml +++ /dev/null @@ -1,153 +0,0 @@ - - - 4.0.0 - - com.twelvemonkeys.sandbox - sandbox - 3.1-SNAPSHOT - - sandbox-swing - jar - TwelveMonkeys :: Sandbox :: Swing - - The TwelveMonkeys Swing Sandbox. Experimental stuff. - - - - - /Library/JavaFX/Home - - - - - com.twelvemonkeys.common - common-lang - compile - - - com.twelvemonkeys.common - common-io - compile - - - com.twelvemonkeys.common - common-image - compile - - - com.twelvemonkeys.swing - swing-core - compile - - - com.twelvemonkeys.swing - swing-application - compile - - - com.twelvemonkeys.imageio - imageio-core - provided - - - - - - com.sun.javafx - javafx-common - 1.3 - system - ${javafx_home}/lib/desktop/javafx-common.jar - - - com.sun.javafx - javafx-io - 1.3 - system - ${javafx_home}/lib/desktop/javafx-io.jar - - - com.sun.javafx - javafx-geom - 1.3 - system - ${javafx_home}/lib/desktop/javafx-geom.jar - - - com.sun.javafx - javafx-ui-commmon - 1.3 - system - ${javafx_home}/lib/desktop/javafx-ui-common.jar - - - com.sun.javafx - javafx-ui-controls - 1.3 - system - ${javafx_home}/lib/desktop/javafx-ui-controls.jar - - - com.sun.javafx - javafx-ui-charts - 1.3 - system - ${javafx_home}/lib/desktop/javafx-ui-charts.jar - - - com.sun.javafx - javafx-ui-desktop - 1.3 - system - ${javafx_home}/lib/desktop/javafx-ui-desktop.jar - - - com.sun.javafx - javafx-ui-swing - 1.3 - system - ${javafx_home}/lib/desktop/javafx-ui-swing.jar - - - com.sun.javafx - javafx-ext-swing - 1.3 - system - ${javafx_home}/lib/desktop/javafx-ext-swing.jar - - - com.sun.javafx - javafx-xfdloader - 1.3 - system - ${javafx_home}/lib/desktop/fxdloader.jar - - - com.sun.javafx - javafx-websvc - 1.3 - system - ${javafx_home}/lib/desktop/websvc.jar - - - - - - com.sun.javafx.jmc - javafx-jmc - 1.3 - system - ${javafx_home}/lib/desktop/jmc.jar - - - com.sun.javafx.scriptapi - javafx-scriptapi - 1.3 - system - ${javafx_home}/lib/desktop/script-api.jar - - - - diff --git a/sandbox/sandbox-swing/src/main/java/com/twelvemonkeys/swing/filechooser/FileSystemViews.java b/sandbox/sandbox-swing/src/main/java/com/twelvemonkeys/swing/filechooser/FileSystemViews.java deleted file mode 100644 index f08b366d..00000000 --- a/sandbox/sandbox-swing/src/main/java/com/twelvemonkeys/swing/filechooser/FileSystemViews.java +++ /dev/null @@ -1,207 +0,0 @@ -package com.twelvemonkeys.swing.filechooser; - -import com.twelvemonkeys.lang.Platform; -import com.twelvemonkeys.lang.Validate; - -import javax.swing.*; -import javax.swing.filechooser.FileSystemView; -import javax.swing.filechooser.FileView; -import javax.swing.plaf.FileChooserUI; -import java.io.File; -import java.io.IOException; - -/** - * FileSystemViews - * - * @author Harald Kuhr - * @author last modified by $Author: haraldk$ - * @version $Id: FileSystemViews.java,v 1.0 Jan 14, 2010 3:19:51 PM haraldk Exp$ - */ -public final class FileSystemViews { - - public static FileSystemView getFileSystemView() { - if (Platform.os() == Platform.OperatingSystem.MacOS) { - return ProxyFileSystemView.instance; - } - - return FileSystemView.getFileSystemView(); - } - - private static class ProxyFileSystemView extends FileSystemView { - - private static final FileSystemView instance = createFSV(); - - private static FileSystemView createFSV() { - FileSystemView view = FileSystemView.getFileSystemView(); - - try { - FileChooserUI ui = null; -/* NOTE: The following is faster, but does not work reliably, as getSystemTypeDescription will return null... - - // The below is really a lot of hassle to avoid creating a JFileChooser. Maybe not a good idea? - String uiClassName = UIManager.getString("FileChooserUI"); - try { - @SuppressWarnings({"unchecked"}) - Class uiClass = (Class) Class.forName(uiClassName); - @SuppressWarnings({"unchecked"}) - Constructor[] constructors = uiClass.getDeclaredConstructors(); - for (Constructor constructor : constructors) { - if (!constructor.isAccessible()) { - constructor.setAccessible(true); - } - - Class[] parameterTypes = constructor.getParameterTypes(); - - // Test the two most likely constructors - if (parameterTypes.length == 0) { - ui = (FileChooserUI) constructor.newInstance(); - break; - } - else if (parameterTypes.length == 1 && parameterTypes[0] == JFileChooser.class) { - ui = (FileChooserUI) constructor.newInstance((JFileChooser) null); - break; - } - } - } - catch (Exception ignore) { - ignore.printStackTrace(); - } - - if (ui == null) { -*/ - // Somewhat slower, but should work even if constructors change - ui = new JFileChooser().getUI(); -// } - - return new ProxyFileSystemView(ui.getFileView(null), view); - } - catch (Throwable ignore) { - } - - // Fall back to default view - return view; - } - - private final FileView uiView; - private final FileSystemView defaultView; - - public ProxyFileSystemView(final FileView pUIView, final FileSystemView pDefaultView) { - Validate.notNull(pUIView, "uiView"); - Validate.notNull(pDefaultView, "defaultFileSystemView"); - - uiView = pUIView; - defaultView = pDefaultView; - } - - @Override - public Boolean isTraversable(File f) { - return uiView.isTraversable(f); - } - - @Override - public String getSystemDisplayName(File f) { - return uiView.getName(f); - } - - @Override - public String getSystemTypeDescription(File f) { - // TODO: Create something that gives a proper description here on the Mac... - return uiView.getTypeDescription(f); - } - - @Override - public Icon getSystemIcon(File f) { - return uiView.getIcon(f); - } - - @Override - public boolean isRoot(File f) { - return defaultView.isRoot(f); - } - - @Override - public boolean isParent(File folder, File file) { - return defaultView.isParent(folder, file); - } - - @Override - public File getChild(File parent, String fileName) { - return defaultView.getChild(parent, fileName); - } - - @Override - public boolean isFileSystem(File f) { - return defaultView.isFileSystem(f); - } - - @Override - public boolean isHiddenFile(File f) { - return defaultView.isHiddenFile(f); - } - - @Override - public boolean isFileSystemRoot(File dir) { - return defaultView.isFileSystemRoot(dir); - } - - @Override - public boolean isDrive(File dir) { - return defaultView.isDrive(dir); - } - - @Override - public boolean isFloppyDrive(File dir) { - return defaultView.isFloppyDrive(dir); - } - - @Override - public boolean isComputerNode(File dir) { - return defaultView.isComputerNode(dir); - } - - @Override - public File[] getRoots() { - return defaultView.getRoots(); - } - - @Override - public File getHomeDirectory() { - return defaultView.getHomeDirectory(); - } - - @Override - public File getDefaultDirectory() { - return defaultView.getDefaultDirectory(); - } - - @Override - public File createFileObject(File dir, String filename) { - return defaultView.createFileObject(dir, filename); - } - - @Override - public File createFileObject(String path) { - return defaultView.createFileObject(path); - } - - @Override - public File[] getFiles(File dir, boolean useFileHiding) { - return defaultView.getFiles(dir, useFileHiding); - } - - @Override - public File getParentDirectory(File dir) { - return defaultView.getParentDirectory(dir); - } - - @Override - public File createNewFolder(File containingDir) throws IOException { - return defaultView.createNewFolder(containingDir); - } - - @Override - public String toString() { - return super.toString() + "[" + uiView + ", " + defaultView + "]"; - } - } -}