1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/samples/delegatingwriterfinal/build.xml Sat Jun 14 09:53:06 2008 +0200
1.3 @@ -0,0 +1,71 @@
1.4 +<?xml version="1.0" encoding="UTF-8"?>
1.5 +<project name="Build Script" default="test" basedir=".">
1.6 + <target name="clean">
1.7 + <delete dir="build"/>
1.8 + </target>
1.9 +
1.10 + <target name="build" depends="-libraries">
1.11 + <antcall target="-build-one">
1.12 + <param name="version" value="api1.0"/>
1.13 + </antcall>
1.14 + <antcall target="-build-one">
1.15 + <param name="version" value="api2.0"/>
1.16 + </antcall>
1.17 +
1.18 + <antcall target="-build-one">
1.19 + <param name="version" value="test"/>
1.20 + <param name="cp" value="build/api1.0/classes:${junit.jar}"/>
1.21 + </antcall>
1.22 + </target>
1.23 +
1.24 + <target name="test" depends="build">
1.25 + <echo level="info" message="Running the Implementation against Version 1.0 of the API. This should succeeds."/>
1.26 + <antcall target="-run-one">
1.27 + <param name="version" value="api1.0"/>
1.28 + </antcall>
1.29 + <echo level="info" message="Running the Implementation against Version 2.0 of the API. This should fail."/>
1.30 + <antcall target="-run-one">
1.31 + <param name="version" value="api2.0"/>
1.32 + </antcall>
1.33 + </target>
1.34 +
1.35 + <!-- support methods -->
1.36 +
1.37 + <target name="-libraries">
1.38 + <ant dir="../libs/"/>
1.39 +
1.40 + <property name="junit.jar" location="../libs/dist/junit-4.4.jar"/>
1.41 + </target>
1.42 +
1.43 + <target name="-run-one">
1.44 + <fail message="You need to specify API version number" unless="version"/>
1.45 + <mkdir dir="build/testresults"/>
1.46 + <junit dir="build/test/classes" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" showoutput="true">
1.47 + <batchtest todir="build/testresults">
1.48 + <fileset dir="build/test/classes">
1.49 + <filename name="**/*Test.class"/>
1.50 + </fileset>
1.51 + </batchtest>
1.52 + <classpath>
1.53 + <path location="build/${version}/classes"/>
1.54 + <path location="build/test/classes"/>
1.55 + <path location="${junit.jar}"/>
1.56 + </classpath>
1.57 + <formatter type="brief" usefile="false"/>
1.58 + <formatter type="xml"/>
1.59 + </junit>
1.60 + </target>
1.61 +
1.62 + <target name="-build-one">
1.63 + <fail message="You need to specify version number" unless="version"/>
1.64 +
1.65 + <mkdir dir="build/${version}/classes"/>
1.66 + <property name="cp" value=""/>
1.67 + <javac
1.68 + srcdir="src-${version}"
1.69 + destdir="build/${version}/classes"
1.70 + source="1.5" target="1.5"
1.71 + classpath="${cp}"
1.72 + />
1.73 + </target>
1.74 +</project>
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/samples/delegatingwriterfinal/nbproject/project.xml Sat Jun 14 09:53:06 2008 +0200
2.3 @@ -0,0 +1,89 @@
2.4 +<?xml version="1.0" encoding="UTF-8"?>
2.5 +<project xmlns="http://www.netbeans.org/ns/project/1" xmlns:ns4="null">
2.6 + <type>org.netbeans.modules.ant.freeform</type>
2.7 + <configuration>
2.8 + <general-data xmlns="http://www.netbeans.org/ns/freeform-project/1">
2.9 + <name>delegatingwriterfinal</name>
2.10 + </general-data>
2.11 + <general-data xmlns="http://www.netbeans.org/ns/freeform-project/2">
2.12 + <!-- Do not use Project Properties customizer when editing this file manually. -->
2.13 + <name>delegatingwriterfinal</name>
2.14 + <properties/>
2.15 + <folders>
2.16 + <source-folder>
2.17 + <label>src-api1.0</label>
2.18 + <type>java</type>
2.19 + <location>src-api1.0</location>
2.20 + <encoding>UTF-8</encoding>
2.21 + </source-folder>
2.22 + <source-folder>
2.23 + <label>src-api2.0</label>
2.24 + <type>java</type>
2.25 + <location>src-api2.0</location>
2.26 + <encoding>UTF-8</encoding>
2.27 + </source-folder>
2.28 + <source-folder>
2.29 + <label>test</label>
2.30 + <type>java</type>
2.31 + <location>src-test</location>
2.32 + <encoding>UTF-8</encoding>
2.33 + </source-folder>
2.34 + </folders>
2.35 + <ide-actions>
2.36 + <action name="build">
2.37 + <target>build</target>
2.38 + </action>
2.39 + <action name="clean">
2.40 + <target>clean</target>
2.41 + </action>
2.42 + <action name="test">
2.43 + <target>test</target>
2.44 + </action>
2.45 + <action name="rebuild">
2.46 + <target>clean</target>
2.47 + <target>build</target>
2.48 + </action>
2.49 + </ide-actions>
2.50 + <view>
2.51 + <items>
2.52 + <source-folder style="packages">
2.53 + <label>API Version 1.0</label>
2.54 + <location>src-api1.0</location>
2.55 + </source-folder>
2.56 + <source-folder style="packages">
2.57 + <label>API Version 2.0</label>
2.58 + <location>src-api2.0</location>
2.59 + </source-folder>
2.60 + <source-folder style="packages">
2.61 + <label>Usage of the API</label>
2.62 + <location>src-test</location>
2.63 + </source-folder>
2.64 + <source-file>
2.65 + <location>build.xml</location>
2.66 + </source-file>
2.67 + </items>
2.68 + <context-menu>
2.69 + <ide-action name="build"/>
2.70 + <ide-action name="rebuild"/>
2.71 + <ide-action name="clean"/>
2.72 + <ide-action name="test"/>
2.73 + </context-menu>
2.74 + </view>
2.75 + </general-data>
2.76 + <java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/1">
2.77 + <compilation-unit>
2.78 + <package-root>src-api1.0</package-root>
2.79 + <source-level>1.5</source-level>
2.80 + </compilation-unit>
2.81 + <compilation-unit>
2.82 + <package-root>src-api2.0</package-root>
2.83 + <source-level>1.5</source-level>
2.84 + </compilation-unit>
2.85 + <compilation-unit>
2.86 + <package-root>src-test</package-root>
2.87 + <classpath mode="compile">src-api1.0:../libs/dist/junit-4.4.jar</classpath>
2.88 + <source-level>1.5</source-level>
2.89 + </compilation-unit>
2.90 + </java-data>
2.91 + </configuration>
2.92 +</project>
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/samples/delegatingwriterfinal/src-api1.0/api/Writer.java Sat Jun 14 09:53:06 2008 +0200
3.3 @@ -0,0 +1,96 @@
3.4 +package api;
3.5 +
3.6 +import java.io.BufferedWriter;
3.7 +import java.io.IOException;
3.8 +
3.9 +/** Fixing the problem caused by mixing subclassing and delegation in
3.10 + * the <code>java.io.BufferedWriter</code>
3.11 + *
3.12 + * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
3.13 + */
3.14 +public final class Writer {
3.15 + private final Impl impl;
3.16 +
3.17 + private Writer(Impl impl) {
3.18 + this.impl = impl;
3.19 + }
3.20 + public final void write(int c) throws IOException {
3.21 + char[] arr = { (char)c };
3.22 + impl.write(arr, 0, 1);
3.23 + }
3.24 +
3.25 + public final void write(char cbuf[]) throws IOException {
3.26 + impl.write(cbuf, 0, cbuf.length);
3.27 + }
3.28 + public final void write(char cbuf[], int off, int len) throws IOException {
3.29 + impl.write(cbuf, off, len);
3.30 + }
3.31 + public final void write(String str) throws IOException {
3.32 + impl.write(str, 0, str.length());
3.33 + }
3.34 + public final void write(String str, int off, int len) throws IOException {
3.35 + impl.write(str, off, len);
3.36 + }
3.37 + public final void flush() throws IOException {
3.38 + impl.flush();
3.39 + }
3.40 + public final void close() throws IOException {
3.41 + impl.close();
3.42 + }
3.43 +
3.44 + public static Writer create(Impl impl) {
3.45 + return new Writer(impl);
3.46 + }
3.47 +
3.48 + public static Writer create(final java.io.Writer w) {
3.49 + return new Writer(new Impl() {
3.50 + public void write(String str, int off, int len) throws IOException {
3.51 + w.write(str, off, len);
3.52 + }
3.53 +
3.54 + public void write(char[] arr, int off, int len) throws IOException {
3.55 + w.write(arr, off, len);
3.56 + }
3.57 +
3.58 + public void close() throws IOException {
3.59 + w.close();
3.60 + }
3.61 +
3.62 + public void flush() throws IOException {
3.63 + w.flush();
3.64 + }
3.65 + });
3.66 + }
3.67 +
3.68 + public static Writer createBuffered(final Writer out) {
3.69 + class Delegate extends java.io.Writer {
3.70 + @Override
3.71 + public void write(char[] cbuf, int off, int len) throws IOException {
3.72 + out.write(cbuf, off, len);
3.73 + }
3.74 +
3.75 + @Override
3.76 + public void flush() throws IOException {
3.77 + out.flush();
3.78 + }
3.79 +
3.80 + @Override
3.81 + public void close() throws IOException {
3.82 + out.close();
3.83 + }
3.84 +
3.85 + }
3.86 + return create(new BufferedWriter(new Delegate()));
3.87 + }
3.88 +
3.89 +
3.90 + public static interface Impl {
3.91 + public void close() throws IOException;
3.92 + public void flush() throws IOException;
3.93 + public void write(String str, int off, int len) throws IOException;
3.94 + public void write(char[] arr, int off, int len) throws IOException;
3.95 + }
3.96 +
3.97 +
3.98 +
3.99 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/samples/delegatingwriterfinal/src-api2.0/api/CharSeq.java Sat Jun 14 09:53:06 2008 +0200
4.3 @@ -0,0 +1,56 @@
4.4 +package api;
4.5 +
4.6 +/**
4.7 + *
4.8 + * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
4.9 + */
4.10 +final class CharSeq implements CharSequence {
4.11 + final char[] arr;
4.12 + final int off;
4.13 + final int len;
4.14 + final int c;
4.15 +
4.16 + public CharSeq(int c) {
4.17 + this.arr = null;
4.18 + this.off = 0;
4.19 + this.len = 1;
4.20 + this.c = c;
4.21 + }
4.22 +
4.23 + public CharSeq(char[] arr, int off, int len) {
4.24 + this.arr = arr;
4.25 + this.off = off;
4.26 + this.len = len;
4.27 + this.c = -1;
4.28 + }
4.29 +
4.30 + public int length() {
4.31 + return arr == null ? 1 : len;
4.32 + }
4.33 +
4.34 + public char charAt(int index) {
4.35 + if (index < 0) {
4.36 + throw new IndexOutOfBoundsException();
4.37 + }
4.38 + if (arr == null) {
4.39 + if (index > 0) {
4.40 + throw new IndexOutOfBoundsException();
4.41 + }
4.42 + return (char)c;
4.43 + } else {
4.44 + if (index >= len) {
4.45 + throw new IndexOutOfBoundsException();
4.46 + }
4.47 + return arr[off + index];
4.48 + }
4.49 + }
4.50 +
4.51 + public CharSequence subSequence(int start, int end) {
4.52 + if (end >= this.len) {
4.53 + throw new IndexOutOfBoundsException();
4.54 + }
4.55 + char[] array = arr == null ? new char[]{ (char)c } : arr;
4.56 + return new CharSeq(array, off + start, off + end);
4.57 + }
4.58 +
4.59 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/samples/delegatingwriterfinal/src-api2.0/api/Writer.java Sat Jun 14 09:53:06 2008 +0200
5.3 @@ -0,0 +1,41 @@
5.4 +package api;
5.5 +
5.6 +import java.io.IOException;
5.7 +
5.8 +/** Fixing the problem caused by mixing subclassing and delegation in
5.9 + * the <code>java.io.BufferedWriter</code>
5.10 + *
5.11 + * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
5.12 + */
5.13 +public final class Writer {
5.14 + private final Impl impl;
5.15 +
5.16 + private Writer(Impl impl) {
5.17 + this.impl = impl;
5.18 + }
5.19 + public final void write(int c) throws IOException {
5.20 + impl.write(new CharSeq(c));
5.21 + }
5.22 +
5.23 + public final void write(char cbuf[]) throws IOException {
5.24 + impl.write(new CharSeq(cbuf, 0, cbuf.length));
5.25 + }
5.26 + public final void write(char cbuf[], int off, int len) throws IOException {
5.27 + impl.write(new CharSeq(cbuf, off, len));
5.28 + }
5.29 + public final void write(String str) throws IOException {
5.30 + impl.write(str);
5.31 + }
5.32 + public final void write(String str, int off, int len) throws IOException {
5.33 + impl.write(str.subSequence(off, off + len));
5.34 + }
5.35 +
5.36 +
5.37 +
5.38 + public static interface Impl {
5.39 + public void write(CharSequence seq) throws IOException;
5.40 + }
5.41 +
5.42 +
5.43 +
5.44 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/samples/delegatingwriterfinal/src-test/api/usage/BufferedWriterCryptoTest.java Sat Jun 14 09:53:06 2008 +0200
6.3 @@ -0,0 +1,37 @@
6.4 +
6.5 +package api.usage;
6.6 +
6.7 +import api.Writer;
6.8 +import java.io.IOException;
6.9 +import java.io.StringWriter;
6.10 +import java.io.StringWriter;
6.11 +import org.junit.Before;
6.12 +import org.junit.Test;
6.13 +import static org.junit.Assert.*;
6.14 +
6.15 +/** Converting the Crypto example to the APIs that split client and provider
6.16 + * concerns and do not mix delegation and subclassing.
6.17 + *
6.18 + * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
6.19 + */
6.20 +public class BufferedWriterCryptoTest {
6.21 + private StringWriter writer;
6.22 +
6.23 +
6.24 + public BufferedWriterCryptoTest() {
6.25 + }
6.26 +
6.27 + @Before
6.28 + public void setUp() {
6.29 + writer = new StringWriter();
6.30 + }
6.31 +
6.32 + @Test
6.33 + public void testBehaviourOfRealBufferInJDKWorksFine() throws IOException {
6.34 + Writer bufferedWriter = CryptoWriter.create(Writer.create(writer));
6.35 + bufferedWriter.write("VMS");
6.36 + bufferedWriter.flush();
6.37 + assertEquals("Converted", "WNT", writer.toString());
6.38 + }
6.39 +
6.40 +}
6.41 \ No newline at end of file
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/samples/delegatingwriterfinal/src-test/api/usage/CryptoWriter.java Sat Jun 14 09:53:06 2008 +0200
7.3 @@ -0,0 +1,60 @@
7.4 +
7.5 +package api.usage;
7.6 +
7.7 +import api.Writer;
7.8 +import java.io.IOException;
7.9 +
7.10 +
7.11 +/** Writer alters each char from 'A' to 'Z' range with next one just like
7.12 + * old Romans did.
7.13 + *
7.14 + * @author Jaroslav Tulach
7.15 + */
7.16 +public class CryptoWriter implements Writer.Impl {
7.17 + private Writer out;
7.18 +
7.19 + private CryptoWriter(Writer out) {
7.20 + this.out = out;
7.21 + }
7.22 +
7.23 +
7.24 + public static Writer create(Writer out) {
7.25 + return Writer.create(new CryptoWriter(out));
7.26 + }
7.27 +
7.28 + @Override
7.29 + public void write(char[] cbuf, int off, int len) throws IOException {
7.30 + char[] arr = new char[len];
7.31 + for (int i = 0; i < len; i++) {
7.32 + arr[i] = convertChar(cbuf[off + i]);
7.33 + }
7.34 + out.write(arr, 0, len);
7.35 + }
7.36 +
7.37 + @Override
7.38 + public void write(String str, int off, int len) throws IOException {
7.39 + StringBuffer sb = new StringBuffer();
7.40 + for (int i = 0; i < len; i++) {
7.41 + sb.append(convertChar(str.charAt(off + i)));
7.42 + }
7.43 + out.write(sb.toString(), 0, len);
7.44 + }
7.45 +
7.46 + private char convertChar(int c) {
7.47 + if (c == 'Z') {
7.48 + return 'A';
7.49 + }
7.50 + if (c == 'z') {
7.51 + return 'a';
7.52 + }
7.53 + return (char)(c + 1);
7.54 + }
7.55 +
7.56 + public void close() throws IOException {
7.57 + out.close();
7.58 + }
7.59 +
7.60 + public void flush() throws IOException {
7.61 + out.flush();
7.62 + }
7.63 +}