Remove core/io
Project: http://git-wip-us.apache.org/repos/asf/zest-java/repo Commit: http://git-wip-us.apache.org/repos/asf/zest-java/commit/37ce367a Tree: http://git-wip-us.apache.org/repos/asf/zest-java/tree/37ce367a Diff: http://git-wip-us.apache.org/repos/asf/zest-java/diff/37ce367a Branch: refs/heads/develop Commit: 37ce367a7d48496d191d867c3cc536b823b5ade1 Parents: 888e429 Author: Paul Merlin <[email protected]> Authored: Fri Dec 9 09:56:20 2016 +0100 Committer: Paul Merlin <[email protected]> Committed: Fri Dec 9 09:56:20 2016 +0100 ---------------------------------------------------------------------- .../apache/zest/gradle/RootProjectPlugin.groovy | 1 - .../org/apache/zest/gradle/ZestExtension.groovy | 1 - core/api/build.gradle | 2 +- core/api/src/docs/valuecomposite.txt | 20 +- .../zest/api/value/DocumentationSupport.java | 32 +- core/io/build.gradle | 27 - core/io/dev-status.xml | 36 -- core/io/src/docs/io.txt | 217 -------- core/io/src/docs/reference/ref-io.txt | 18 - .../src/main/java/org/apache/zest/io/Files.java | 36 -- .../src/main/java/org/apache/zest/io/Input.java | 39 -- .../main/java/org/apache/zest/io/Inputs.java | 496 ----------------- .../main/java/org/apache/zest/io/Output.java | 46 -- .../main/java/org/apache/zest/io/Outputs.java | 534 ------------------- .../main/java/org/apache/zest/io/Receiver.java | 42 -- .../main/java/org/apache/zest/io/Sender.java | 45 -- .../java/org/apache/zest/io/Transforms.java | 441 --------------- .../main/java/org/apache/zest/io/package.html | 24 - .../org/apache/zest/io/InputOutputTest.java | 386 -------------- .../org/apache/zest/io/docsupport/IoDocs.java | 54 -- core/io/src/test/resources/iotest.txt | 4 - manual/src/docs/tutorials/howto-use-io.txt | 329 ------------ manual/src/docs/userguide/core.txt | 13 - manual/src/docs/website/tutorials.txt | 5 - .../org/apache/zest/manual/recipes/io/Docs.java | 39 -- settings.gradle | 1 - 26 files changed, 17 insertions(+), 2871 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/zest-java/blob/37ce367a/buildSrc/src/main/groovy/org/apache/zest/gradle/RootProjectPlugin.groovy ---------------------------------------------------------------------- diff --git a/buildSrc/src/main/groovy/org/apache/zest/gradle/RootProjectPlugin.groovy b/buildSrc/src/main/groovy/org/apache/zest/gradle/RootProjectPlugin.groovy index 8c058d1..afc690a 100644 --- a/buildSrc/src/main/groovy/org/apache/zest/gradle/RootProjectPlugin.groovy +++ b/buildSrc/src/main/groovy/org/apache/zest/gradle/RootProjectPlugin.groovy @@ -163,7 +163,6 @@ class RootProjectPlugin implements Plugin<Project> options.group( [ "Core API" : [ "org.apache.zest.api", "org.apache.zest.api.*", - "org.apache.zest.io", "org.apache.zest.functional" ], "Core Bootstrap": [ "org.apache.zest.bootstrap", "org.apache.zest.bootstrap.*" ], http://git-wip-us.apache.org/repos/asf/zest-java/blob/37ce367a/buildSrc/src/main/groovy/org/apache/zest/gradle/ZestExtension.groovy ---------------------------------------------------------------------- diff --git a/buildSrc/src/main/groovy/org/apache/zest/gradle/ZestExtension.groovy b/buildSrc/src/main/groovy/org/apache/zest/gradle/ZestExtension.groovy index de1f0d4..f57d8b4 100644 --- a/buildSrc/src/main/groovy/org/apache/zest/gradle/ZestExtension.groovy +++ b/buildSrc/src/main/groovy/org/apache/zest/gradle/ZestExtension.groovy @@ -50,7 +50,6 @@ class ZestExtension Dependency runtime = core( 'runtime' ) Dependency bootstrap = core( 'bootstrap' ) Dependency testsupport = core( 'testsupport' ) - Dependency io = core( 'io' ) Dependency functional = core( 'functional' ) } http://git-wip-us.apache.org/repos/asf/zest-java/blob/37ce367a/core/api/build.gradle ---------------------------------------------------------------------- diff --git a/core/api/build.gradle b/core/api/build.gradle index 8b717cd..ae8fc0c 100644 --- a/core/api/build.gradle +++ b/core/api/build.gradle @@ -21,7 +21,7 @@ jar { manifest { name = "Apache Zest⢠Core API" } } dependencies { - compile zest.core.io + compile zest.core.functional testCompile zest.core.testsupport testCompile zest.library( 'constraints' ) http://git-wip-us.apache.org/repos/asf/zest-java/blob/37ce367a/core/api/src/docs/valuecomposite.txt ---------------------------------------------------------------------- diff --git a/core/api/src/docs/valuecomposite.txt b/core/api/src/docs/valuecomposite.txt index 8e8a88c..1517015 100644 --- a/core/api/src/docs/valuecomposite.txt +++ b/core/api/src/docs/valuecomposite.txt @@ -121,9 +121,7 @@ In this second example, we ; . use the +ValueSerializer#serialize()+ method to get a JSON representation of the Value, . and finally, use the +ValueDeserializer#eserialize()+ method to create a new Value instance from the JSON state. -Many applications need to stream data. The ValueSerialization API support such use cases in two ways. - -The first one use classic streams. +Many applications need to stream data. The ValueSerialization API support such use cases using classic streams: [snippet,java] ---- @@ -135,19 +133,3 @@ tag=stream . serialize data into the +OutputStream+, . get a handle on an +InputStream+, . deserialize data from the +InputStream+. - -The second one use the <<core-io>>: - -[snippet,java] ----- -source=core/api/src/test/java/org/apache/zest/api/value/DocumentationSupport.java -tag=io ----- - - . get a handle on a source of values and a +Writer+, - . prepare the serialization +Function+, - . serialize a collection of values, one serialized value per line, - . get a handle on a serialized values +Reader+ and create a new empty +List+ of values, - . prepare the deserialization +Function+, - . deserialize a collection of values from read lines. - http://git-wip-us.apache.org/repos/asf/zest-java/blob/37ce367a/core/api/src/test/java/org/apache/zest/api/value/DocumentationSupport.java ---------------------------------------------------------------------- diff --git a/core/api/src/test/java/org/apache/zest/api/value/DocumentationSupport.java b/core/api/src/test/java/org/apache/zest/api/value/DocumentationSupport.java index 26a64e2..6d4a08a 100644 --- a/core/api/src/test/java/org/apache/zest/api/value/DocumentationSupport.java +++ b/core/api/src/test/java/org/apache/zest/api/value/DocumentationSupport.java @@ -24,14 +24,12 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.Reader; -import java.io.StringReader; +import java.io.PrintWriter; import java.io.StringWriter; -import java.io.Writer; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.function.Function; +import java.util.stream.Stream; import org.apache.zest.api.injection.scope.Service; import org.apache.zest.api.property.Property; import org.apache.zest.api.structure.Application; @@ -42,14 +40,11 @@ import org.apache.zest.bootstrap.AssemblyException; import org.apache.zest.bootstrap.Energy4Java; import org.apache.zest.bootstrap.ModuleAssembly; import org.apache.zest.bootstrap.unitofwork.DefaultUnitOfWorkAssembler; -import org.apache.zest.io.Inputs; -import org.apache.zest.io.Outputs; -import org.apache.zest.io.Transforms; import org.apache.zest.test.AbstractZestTest; import org.apache.zest.valueserialization.orgjson.OrgJsonValueSerializationAssembler; -import org.junit.Before; import org.junit.Test; +import static java.util.stream.Collectors.toList; import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.assertThat; @@ -172,27 +167,30 @@ public class DocumentationSupport // END SNIPPET: io List<AcmeValue> dataSource = Arrays.asList( AcmeValue.values() ); - StringWriter outputWriter = new StringWriter(); + StringWriter stringOutput = new StringWriter(); + PrintWriter output = new PrintWriter( stringOutput ); + // START SNIPPET: io // (1) - Iterable<AcmeValue> queryResult = dataSource; // Eg. Entities converted to Values - Writer writer = outputWriter; // Eg. to pipe data to another process or to a file + // Eg. Entities converted to Values + Stream<AcmeValue> queryResult = dataSource.stream(); // (2) Function<AcmeValue, String> serialize = valueSerializer.serialize(); // (3) - Inputs.iterable( queryResult ).transferTo( Transforms.map( serialize, Outputs.text( writer ) ) ); + // Eg. pipe data to another process or to a file + queryResult.map( serialize ).forEach( output::println ); // END SNIPPET: io - String string = writer.toString(); - StringReader inputReader = new StringReader( string ); + output.flush(); + String string = stringOutput.toString(); + List<String> input = Arrays.asList( string.split( System.lineSeparator() ) ); // START SNIPPET: io // (4) - Reader reader = inputReader; - List<AcmeValue> values = new ArrayList<AcmeValue>(); + Stream<String> lines = input.stream(); // (5) Function<String, AcmeValue> deserialize = valueDeserializer.deserialize( module, AcmeValue.class ); @@ -200,7 +198,7 @@ public class DocumentationSupport // Deserialization of a collection of AcmeValue from a String. // One serialized AcmeValue per line. // (6) - Inputs.text( reader ).transferTo( Transforms.map( deserialize, Outputs.collection( values ) ) ); + List<AcmeValue> values = lines.map( deserialize ).collect( toList() ); // END SNIPPET: io assertThat( dataSource, equalTo( values ) ); http://git-wip-us.apache.org/repos/asf/zest-java/blob/37ce367a/core/io/build.gradle ---------------------------------------------------------------------- diff --git a/core/io/build.gradle b/core/io/build.gradle deleted file mode 100644 index 0e0c50a..0000000 --- a/core/io/build.gradle +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. - * - * - */ - -jar { manifest { name = "Apache Zest⢠I/O" } } - -dependencies { - compile zest.core.functional - - testCompile zest.core.testsupport -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/37ce367a/core/io/dev-status.xml ---------------------------------------------------------------------- diff --git a/core/io/dev-status.xml b/core/io/dev-status.xml deleted file mode 100644 index 412d5e3..0000000 --- a/core/io/dev-status.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!-- - ~ Licensed to the Apache Software Foundation (ASF) under one - ~ or more contributor license agreements. See the NOTICE file - ~ distributed with this work for additional information - ~ regarding copyright ownership. The ASF licenses this file - ~ to you 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. - ~ - ~ - --> -<module xmlns="http://zest.apache.org/schemas/2008/dev-status/1" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://zest.apache.org/schemas/2008/dev-status/1 - http://zest.apache.org/schemas/2008/dev-status/1/dev-status.xsd"> - <status> - <codebase>beta</codebase> - <!--none,early,beta,stable,mature--> - <documentation>good</documentation> - <!-- none, brief, good, complete --> - <unittests>good</unittests> - <!-- none, some, good, complete --> - </status> - <licenses> - <license>ALv2</license> - </licenses> -</module> http://git-wip-us.apache.org/repos/asf/zest-java/blob/37ce367a/core/io/src/docs/io.txt ---------------------------------------------------------------------- diff --git a/core/io/src/docs/io.txt b/core/io/src/docs/io.txt deleted file mode 100644 index 3b1cb2e..0000000 --- a/core/io/src/docs/io.txt +++ /dev/null @@ -1,217 +0,0 @@ -////////////////////// - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. -////////////////////// - -[[core-io,I/O API]] -= Core I/O API = - -[devstatus] --------------- -source=core/io/dev-status.xml --------------- - -The Zest⢠Core I/O API is completely generic and not tied to the Zest⢠programming model as a whole. It can be used -independently of Zest, together with the Zest⢠Core Functional API, which the Core I/O API depends on. - -The Zest⢠Core I/O API tries to address the problem around shuffling data around from various I/O inputs and outputs, -possibly with transformations and filtering along the way. It was identified that there is a general mix-up of concerns -in the stereotypical I/O handling codebases that people deal with all the time. The reasoning around this, can be found -in the <<howto-use-io>>, and is recommended reading. - -include::../../build/docs/buildinfo/artifact.txt[] - -== The Problem == -Why does I/O operations in Java have to be so complicated, with nested try/catch/finally and loops? Don't you wish -that the operations could be expressed in a more natural way, such as; - -[source,java] -------------- -File source = ... -File destination = ... -source.copyTo( destination ); -------------- - -It seems natural to do, yet it is not present for us. We need to involve FileInputStream/FileOutputStream, wrap them -in Buffered versions of it, do our own looping, close the streams afterwards and what not. So, the java.io.File does -not have this simple feature and in the Zest⢠Core API, we need to work around this limitation. We also want to -make the abstraction a little bit more encompassing than "just" files. So how does that look like then? - -== First Examples == -The most common inputs and outputs are collected in the org.apache.zest.io.Inputs and org.apache.zest.io.Outputs classes as static -factory methods, but you can create your (more about that later). - -So, we want to read a text file and write the content into another text file, right? This is how it is done; - -[snippet,java] ------------ -source=core/io/src/test/java/org/apache/zest/io/docsupport/IoDocs.java -tag=io1 ------------ - -Pretty much self-explanatory, wouldn't you say? But what happened to the handling of exceptions and closing of -resources? It is all handled inside the Zest⢠Core I/O API. There is nothing you can forget to do. - -Another simple example, where we want to count the number of lines in the text; - -[snippet,java] ------------ -source=core/io/src/test/java/org/apache/zest/io/docsupport/IoDocs.java -tag=io2 ------------ - -The Counter is a <<core-functional>> which gets injected into the transfer. - -== The 3 Parts == -Ok, so we have seen that the end result can become pretty compelling. How does it work? - -I/O is defined as a process of moving data from an Input, via one or more Transforms to an Output. The Input could -be a File or a String, the transformation could be a filter, conversion or a function and finally the Output -destination could be a File, String or an OutputStream. It is important to note that there is a strong separation of -concern between them. Let's look at the on at a time. - -== org.apache.zest.io.Input == -This interface simply has a transferTo() method, which takes an Output. The formal definition is; - -[snippet,java] --------------- -source=core/io/src/main/java/org/apache/zest/io/Input.java -tag=input --------------- - -What on earth is all this genericized Exceptions? Well, it abstracts away the explicit Exception that implementations -may throw (or not). So instead of demanding that all I/O must throw the java.io.IOException, as is the case in the -JDK classes, it is up to the implementation to declare what it may throw. That is found in the SenderThrowable generic -of the interface. - -But hold on a second. Why is an Input throwing a "sender" exception? Well, think again. The Input is feeding "something" -with data. It takes it from some source and "sends it" to the downstream chain, eventually reaching an Output, which -likewise is the ultimate "receiver". - -So, then, the method transferTo() contains the declaration of the downstream receiver's possible Exception -(ReceiverThrowable) which the transferTo() method may also throw as the data may not be accepted and such exception -will bubble up to the transferTo() method (the client's view of the transfer). - -== org.apache.zest.io.Output == -The output interface is likewise fairly simple; - -[snippet,java] --------------- -source=core/io/src/main/java/org/apache/zest/io/Output.java -tag=output --------------- - -It can simply receive data from a org.apache.zest.io.Sender. - -Hey, hold on! Why is it not receiving from an Input? Because the Input is the client's entry point and of no use to -the Output as such. Instead, the Output will tell the Sender (which is handed to from the Input or an transformation) -to which Receiver the content should be sent to. - -Complicated? Perhaps not trivial to get your head around it at first, but the chain is; - -Input passes a Sender to the Output which tells the Sender which Receiver the data should be sent to. - -The reason for this is that we need to separate the concerns properly. Input is a starting point, but it emits something -which is represented by the Sender. Likewise the destination is an Output, but it receives the data via its Receiver -interface. For O/S resources, they are handled purely inside the Input and Output implementations, where are the -Sender/Receiver are effectively dealing with the data itself. - -== org.apache.zest.io.Transforms == -The 3 component in the Zest⢠Core I/O API is the transformations that are possible. Interestingly enough, with the -above separation of concerns, we don't need an InputOutput type that can both receive and send data. Instead, we -simply need to prepare easy to use static factory methods, which are found in the org.apache.zest.io.Transforms class. Again, -it is fairly straight forward to create your own Transforms if you need something not provided here. - -The current transformations available are; - - * filter - takes a Specification and only forwards data items conforming to the Specification. - * map - takes a org.apache.zest.functional.Function to convert an item from one type to (potentially) another, and any - possible change along the way. - * filteredMap - is a combination of a filter and a map. If the Specification is satisfied, the map function is - applied, otherwise the item is passed through unaffected. - * lock - A wrapper which protects the Input or Output from simultaneous access. Not a transformation by itself, - but implemented in the same fashion. - -There are also a couple of handy map functions available, such as - - * Log - * ProgressLog - * Counter - * ByteBuffer2String - * Object2String - * String2Bytes - -== Writing a Map Function? == -Let us take a closer look at the implementation of a map function, namely Counter mentioned above and also used in -the section First Example above. - -The implementation is very straight forward. - -[snippet,java] --------------- -source=core/io/src/main/java/org/apache/zest/io/Transforms.java -tag=counter --------------- - -On each call to the map() method, increment the counter field. The client can then retrieve that value after the -transfer is complete, or in a separate thread to show progress. - -Speaking of "progress", so how is the ProgressLog implemented? Glad you asked; - -[snippet,java] --------------- -source=core/io/src/main/java/org/apache/zest/io/Transforms.java -tag=progress --------------- - -It combines the Counter and the Log implementations, so that the count is forwarded to the Log at a given interval, such -as every 1000 items. This may not be what you think a ProgressLog should look like, but it serves as a good example on -how you can combine the general principles found in the Zest⢠Core API package. - -== How to write a filter specification? == -The filter transform takes a regular java.util.function.Predicate as an argument, where the implementation needs to -return *true* or *false* for whether the item passed in is within -the limits. Let's say that you have a IntegerRangeSpecification, which could then be implemented as - -[snippet,java] --------------- -source=core/functional/src/test/java/org/apache/zest/functional/IntegerRangeSpecificationTest.java -tag=specification --------------- - -== Ready-to-use components == -Input and Output implementations at first glance look quite scary. Taking a closer look and it can be followed. But to -simplify for users, the org.apache.zest.io.Inputs and org.apache.zest.io.Outputs contains static factory methods for many useful -sources and destinations. - -== org.apache.zest.io.Inputs == -The current set of ready-to-use Input implementations are; - -[snippet,java] --------------- -source=core/io/src/main/java/org/apache/zest/io/Inputs.java -tag=method --------------- - -== org.apache.zest.io.Outputs == -The current set of ready-to-use Input implementations are; - -[snippet,java] --------------- -source=core/io/src/main/java/org/apache/zest/io/Outputs.java -tag=method --------------- - http://git-wip-us.apache.org/repos/asf/zest-java/blob/37ce367a/core/io/src/docs/reference/ref-io.txt ---------------------------------------------------------------------- diff --git a/core/io/src/docs/reference/ref-io.txt b/core/io/src/docs/reference/ref-io.txt deleted file mode 100644 index fc7aac6..0000000 --- a/core/io/src/docs/reference/ref-io.txt +++ /dev/null @@ -1,18 +0,0 @@ -/////////////////////////////////////////////////////////////// - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. -/////////////////////////////////////////////////////////////// http://git-wip-us.apache.org/repos/asf/zest-java/blob/37ce367a/core/io/src/main/java/org/apache/zest/io/Files.java ---------------------------------------------------------------------- diff --git a/core/io/src/main/java/org/apache/zest/io/Files.java b/core/io/src/main/java/org/apache/zest/io/Files.java deleted file mode 100644 index a70b2f9..0000000 --- a/core/io/src/main/java/org/apache/zest/io/Files.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 org.apache.zest.io; - -import java.io.File; -import java.util.Random; - -/** - * Utility class for files. - */ -public class Files -{ - private static Random random = new Random(); - - public static File createTemporayFileOf( File file ) - { - return new File( file.getAbsolutePath() + "_" + Math.abs( random.nextLong() ) ); - } -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/37ce367a/core/io/src/main/java/org/apache/zest/io/Input.java ---------------------------------------------------------------------- diff --git a/core/io/src/main/java/org/apache/zest/io/Input.java b/core/io/src/main/java/org/apache/zest/io/Input.java deleted file mode 100644 index 0841926..0000000 --- a/core/io/src/main/java/org/apache/zest/io/Input.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 org.apache.zest.io; - -/** - * Input source of data. - * <p> - * Invoke transferTo to send data from this input to given output. transferTo can be invoked - * as many times as you want. The transferTo implementation must ensure that any exceptions thrown - * by the Input or the Output which transferred data is sent to is handled properly, i.e. that resources - * are closed. Any client code to transferTo calls should not have to bother with resource management, - * but may catch exceptions anyway for logging and similar purposes. - * </p> - */ -// START SNIPPET: input -public interface Input<T, SenderThrowableType extends Throwable> -{ - <ReceiverThrowableType extends Throwable> void transferTo( Output<? super T, ReceiverThrowableType> output ) - throws SenderThrowableType, ReceiverThrowableType; -} -// END SNIPPET: input http://git-wip-us.apache.org/repos/asf/zest-java/blob/37ce367a/core/io/src/main/java/org/apache/zest/io/Inputs.java ---------------------------------------------------------------------- diff --git a/core/io/src/main/java/org/apache/zest/io/Inputs.java b/core/io/src/main/java/org/apache/zest/io/Inputs.java deleted file mode 100644 index 3a6041a..0000000 --- a/core/io/src/main/java/org/apache/zest/io/Inputs.java +++ /dev/null @@ -1,496 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 org.apache.zest.io; - -import java.io.BufferedOutputStream; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.Reader; -import java.net.URL; -import java.net.URLConnection; -import java.nio.ByteBuffer; -import java.nio.channels.FileChannel; -import java.util.Scanner; -import java.util.zip.GZIPInputStream; -import org.apache.zest.functional.Visitor; - -/** - * Common inputs - */ -public class Inputs -{ - // START SNIPPET: method - - /** - * Read lines from a String. - * - * @param source lines - * - * @return Input that provides lines from the string as strings - */ - public static Input<String, RuntimeException> text( final String source ) - // END SNIPPET: method - { - return new Input<String, RuntimeException>() - { - @Override - public <ReceiverThrowableType extends Throwable> void transferTo( Output<? super String, ReceiverThrowableType> output ) - throws RuntimeException, ReceiverThrowableType - { - - output.receiveFrom( new Sender<String, RuntimeException>() - { - @Override - public <Receiver2ThrowableType extends Throwable> void sendTo( Receiver<? super String, Receiver2ThrowableType> receiver ) - throws Receiver2ThrowableType, RuntimeException - { - Scanner scanner = new Scanner( source ); - while( scanner.hasNextLine() ) - { - receiver.receive( scanner.nextLine() ); - } - } - } ); - } - }; - } - - // START SNIPPET: method - - /** - * Read lines from a Reader. - * - * @param source lines - * - * @return Input that provides lines from the string as strings - */ - public static Input<String, RuntimeException> text( final Reader source ) - // END SNIPPET: method - { - return new Input<String, RuntimeException>() - { - @Override - public <ReceiverThrowableType extends Throwable> void transferTo( Output<? super String, ReceiverThrowableType> output ) - throws RuntimeException, ReceiverThrowableType - { - - output.receiveFrom( new Sender<String, RuntimeException>() - { - @Override - public <Receiver2ThrowableType extends Throwable> void sendTo( Receiver<? super String, Receiver2ThrowableType> receiver ) - throws Receiver2ThrowableType, RuntimeException - { - Scanner scanner = new Scanner( source ); - while( scanner.hasNextLine() ) - { - receiver.receive( scanner.nextLine() ); - } - } - } ); - } - }; - } - - // START SNIPPET: method - - /** - * Read lines from a UTF-8 encoded textfile. - * - * If the filename ends with .gz, then the data is automatically unzipped when read. - * - * @param source textfile with lines separated by \n character - * - * @return Input that provides lines from the textfiles as strings - */ - public static Input<String, IOException> text( final File source ) - // END SNIPPET: method - { - return text( source, "UTF-8" ); - } - - // START SNIPPET: method - - /** - * Read lines from a textfile with the given encoding. - * - * If the filename ends with .gz, then the data is automatically unzipped when read. - * - * @param source textfile with lines separated by \n character - * @param encoding encoding of file, e.g. "UTF-8" - * - * @return Input that provides lines from the textfiles as strings - */ - public static Input<String, IOException> text( final File source, final String encoding ) - // END SNIPPET: method - { - return new Input<String, IOException>() - { - @Override - public <ReceiverThrowableType extends Throwable> void transferTo( Output<? super String, ReceiverThrowableType> output ) - throws IOException, ReceiverThrowableType - { - InputStream stream = new FileInputStream( source ); - - // If file is gzipped, unzip it automatically - if( source.getName().endsWith( ".gz" ) ) - { - stream = new GZIPInputStream( stream ); - } - - try (BufferedReader reader = new BufferedReader( new InputStreamReader( stream, encoding ) )) - { - output.receiveFrom( new Sender<String, IOException>() - { - @Override - public <Receiver2ThrowableType extends Throwable> void sendTo( Receiver<? super String, Receiver2ThrowableType> receiver ) - throws Receiver2ThrowableType, IOException - { - String line; - while( ( line = reader.readLine() ) != null ) - { - receiver.receive( line ); - } - } - } ); - } - } - }; - } - - // START SNIPPET: method - - /** - * Read lines from a textfile at a given URL. - * - * If the content support gzip encoding, then the data is automatically unzipped when read. - * - * The charset in the content-type of the URL will be used for parsing. Default is UTF-8. - * - * @param source textfile with lines separated by \n character - * - * @return Input that provides lines from the textfiles as strings - */ - public static Input<String, IOException> text( final URL source ) - // END SNIPPET: method - { - return new Input<String, IOException>() - { - @Override - public <ReceiverThrowableType extends Throwable> void transferTo( Output<? super String, ReceiverThrowableType> output ) - throws IOException, ReceiverThrowableType - { - URLConnection urlConnection = source.openConnection(); - urlConnection.setRequestProperty( "Accept-Encoding", "gzip" ); - InputStream stream = urlConnection.getInputStream(); - - // If file is gzipped, unzip it automatically - if( "gzip".equals( urlConnection.getContentEncoding() ) ) - { - stream = new GZIPInputStream( stream ); - } - - // Figure out charset given content-type - String contentType = urlConnection.getContentType(); - String charSet = "UTF-8"; - if( contentType.contains( "charset=" ) ) - { - charSet = contentType.substring( contentType.indexOf( "charset=" ) + "charset=".length() ); - } - - try (BufferedReader reader = new BufferedReader( new InputStreamReader( stream, charSet ) )) - { - output.receiveFrom( new Sender<String, IOException>() - { - @Override - public <Receiver2ThrowableType extends Throwable> void sendTo( Receiver<? super String, Receiver2ThrowableType> receiver ) - throws Receiver2ThrowableType, IOException - { - String line; - while( ( line = reader.readLine() ) != null ) - { - receiver.receive( line ); - } - } - } ); - } - } - }; - } - - // START SNIPPET: method - - /** - * Read a file using ByteBuffer of a given size. Useful for transferring raw data. - * - * @param source The file to be read. - * @param bufferSize The size of the byte array. - * - * @return An Input instance to be applied to streaming operations. - */ - public static Input<ByteBuffer, IOException> byteBuffer( final File source, final int bufferSize ) - // END SNIPPET: method - { - return new Input<ByteBuffer, IOException>() - { - @Override - public <ReceiverThrowableType extends Throwable> void transferTo( Output<? super ByteBuffer, ReceiverThrowableType> output ) - throws IOException, ReceiverThrowableType - { - final FileInputStream stream = new FileInputStream( source ); - final FileChannel fci = stream.getChannel(); - - final ByteBuffer buffer = ByteBuffer.allocate( bufferSize ); - - try - { - output.receiveFrom( new Sender<ByteBuffer, IOException>() - { - @Override - public <Receiver2ThrowableType extends Throwable> void sendTo( Receiver<? super ByteBuffer, Receiver2ThrowableType> receiver ) - throws Receiver2ThrowableType, IOException - { - while( fci.read( buffer ) != -1 ) - { - buffer.flip(); - receiver.receive( buffer ); - buffer.clear(); - } - } - } ); - } - finally - { - stream.close(); - } - } - }; - } - - // START SNIPPET: method - - /** - * Read an inputstream using ByteBuffer of a given size. - * - * @param source The InputStream to be read. - * @param bufferSize The size of the byte array. - * - * @return An Input instance to be applied to streaming operations. - */ - public static Input<ByteBuffer, IOException> byteBuffer( final InputStream source, final int bufferSize ) - // END SNIPPET: method - { - return new Input<ByteBuffer, IOException>() - { - @Override - public <ReceiverThrowableType extends Throwable> void transferTo( Output<? super ByteBuffer, ReceiverThrowableType> output ) - throws IOException, ReceiverThrowableType - { - try - { - output.receiveFrom( new Sender<ByteBuffer, IOException>() - { - @Override - public <Receiver2ThrowableType extends Throwable> void sendTo( Receiver<? super ByteBuffer, Receiver2ThrowableType> receiver ) - throws Receiver2ThrowableType, IOException - { - byte[] buffer = new byte[ bufferSize ]; - - int len; - while( ( len = source.read( buffer ) ) != -1 ) - { - ByteBuffer byteBuffer = ByteBuffer.wrap( buffer, 0, len ); - receiver.receive( byteBuffer ); - } - } - } ); - } - finally - { - source.close(); - } - } - }; - } - - // START SNIPPET: method - - /** - * Combine many Input into one single Input. When a transfer is initiated from it all items from all inputs will be transferred - * to the given Output. - * - * @param inputs An Iterable of Input instances to be combined. - * @param <T> The item type of the Input - * @param <SenderThrowableType> The Throwable that might be thrown by the Inputs. - * - * @return A combined Input, allowing for easy aggregation of many Input sources. - */ - public static <T, SenderThrowableType extends Throwable> Input<T, SenderThrowableType> combine( final Iterable<Input<T, SenderThrowableType>> inputs ) - // END SNIPPET: method - { - return new Input<T, SenderThrowableType>() - { - @Override - public <Receiver2ThrowableType extends Throwable> void transferTo( Output<? super T, Receiver2ThrowableType> output ) - throws SenderThrowableType, Receiver2ThrowableType - { - output.receiveFrom( new Sender<T, SenderThrowableType>() - { - @Override - public <ReceiverThrowableType extends Throwable> void sendTo( final Receiver<? super T, ReceiverThrowableType> receiver ) - throws ReceiverThrowableType, SenderThrowableType - { - for( Input<T, SenderThrowableType> input : inputs ) - { - input.transferTo( new Output<T, ReceiverThrowableType>() - { - @Override - public <Sender2ThrowableType extends Throwable> void receiveFrom( Sender<? extends T, Sender2ThrowableType> sender ) - throws ReceiverThrowableType, Sender2ThrowableType - { - sender.sendTo( new Receiver<T, ReceiverThrowableType>() - { - @Override - public void receive( T item ) - throws ReceiverThrowableType - { - receiver.receive( item ); - } - } ); - } - } ); - } - } - } ); - } - }; - } - - // START SNIPPET: method - - /** - * Create an Input that takes its items from the given Iterable. - * - * @param iterable The Iterable to be used as an Input. - * @param <T> The item type of the Input - * - * @return An Input instance that is backed by the Iterable. - */ - public static <T> Input<T, RuntimeException> iterable( final Iterable<T> iterable ) - // END SNIPPET: method - { - return new Input<T, RuntimeException>() - { - @Override - public <ReceiverThrowableType extends Throwable> void transferTo( Output<? super T, ReceiverThrowableType> output ) - throws RuntimeException, ReceiverThrowableType - { - output.receiveFrom( new Sender<T, RuntimeException>() - { - @Override - public <Receiver2ThrowableType extends Throwable> void sendTo( Receiver<? super T, Receiver2ThrowableType> receiver ) - throws Receiver2ThrowableType, RuntimeException - { - for( T item : iterable ) - { - receiver.receive( item ); - } - } - } ); - } - }; - } - - // START SNIPPET: method - - /** - * Create an Input that allows a Visitor to write to an OutputStream. The stream is a BufferedOutputStream, so when enough - * data has been gathered it will send this in chunks of the given size to the Output it is transferred to. The Visitor does not have to call - * close() on the OutputStream, but should ensure that any wrapper streams or writers are flushed so that all data is sent. - * - * @param outputVisitor The OutputStream Visitor that will be backing the Input ByteBuffer. - * @param bufferSize The buffering size. - * - * @return An Input instance of ByteBuffer, that is backed by an Visitor to an OutputStream. - */ - public static Input<ByteBuffer, IOException> output( final Visitor<OutputStream, IOException> outputVisitor, - final int bufferSize - ) - // END SNIPPET: method - { - return new Input<ByteBuffer, IOException>() - { - @Override - public <ReceiverThrowableType extends Throwable> void transferTo( Output<? super ByteBuffer, ReceiverThrowableType> output ) - throws IOException, ReceiverThrowableType - { - output.receiveFrom( new Sender<ByteBuffer, IOException>() - { - @Override - @SuppressWarnings( "unchecked" ) - public <Receiver2ThrowableType extends Throwable> void sendTo( final Receiver<? super ByteBuffer, Receiver2ThrowableType> receiver ) - throws Receiver2ThrowableType, IOException - { - try (OutputStream out = new BufferedOutputStream( new OutputStream() - { - @Override - public void write( int b ) - throws IOException - { - // Ignore - } - - @SuppressWarnings( "NullableProblems" ) - @Override - public void write( byte[] b, int off, int len ) - throws IOException - { - try - { - ByteBuffer byteBuffer = ByteBuffer.wrap( b, 0, len ); - receiver.receive( byteBuffer ); - } - catch( Throwable ex ) - { - throw new IOException( ex ); - } - } - }, bufferSize )) - { - outputVisitor.visit( out ); - } - catch( IOException ex ) - { - throw (Receiver2ThrowableType) ex.getCause(); - } - } - } ); - } - }; - } - - private Inputs() - { - } -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/37ce367a/core/io/src/main/java/org/apache/zest/io/Output.java ---------------------------------------------------------------------- diff --git a/core/io/src/main/java/org/apache/zest/io/Output.java b/core/io/src/main/java/org/apache/zest/io/Output.java deleted file mode 100644 index 11ba3b5..0000000 --- a/core/io/src/main/java/org/apache/zest/io/Output.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 org.apache.zest.io; - -/** - * Output for data. - */ -// START SNIPPET: output -public interface Output<T, ReceiverThrowableType extends Throwable> -{ -// END SNIPPET: output - - /** - * This initiates a transfer from an Input. Implementations should open any resources to be written to - * and then call sender.sendTo() when it is ready to receive data. When sendTo() returns the resource should be - * closed properly. Make sure to handle any exceptions from sendTo. - * - * @param sender the sender of data to this output - * @param <SenderThrowableType> the exception that sendTo can throw - * - * @throws SenderThrowableType the exception that the sender can throw - * @throws ReceiverThrowableType the exception that this output can throw from receiveItem() - */ -// START SNIPPET: output - <SenderThrowableType extends Throwable> void receiveFrom( Sender<? extends T, SenderThrowableType> sender ) - throws ReceiverThrowableType, SenderThrowableType; -} -// END SNIPPET: output http://git-wip-us.apache.org/repos/asf/zest-java/blob/37ce367a/core/io/src/main/java/org/apache/zest/io/Outputs.java ---------------------------------------------------------------------- diff --git a/core/io/src/main/java/org/apache/zest/io/Outputs.java b/core/io/src/main/java/org/apache/zest/io/Outputs.java deleted file mode 100644 index f21204c..0000000 --- a/core/io/src/main/java/org/apache/zest/io/Outputs.java +++ /dev/null @@ -1,534 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 org.apache.zest.io; - -import java.io.BufferedOutputStream; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.nio.ByteBuffer; -import java.nio.channels.FileChannel; -import java.util.Collection; -import java.util.zip.GZIPOutputStream; - -/** - * Utility methods for creating standard Outputs - */ -public class Outputs -{ - // START SNIPPET: method - - /** - * Write lines to a text file with UTF-8 encoding. Separate each line with a newline ("\n" character). If the writing or sending fails, - * the file is deleted. - * <p> - * If the filename ends with .gz, then the data is automatically GZipped. - * </p> - * @param file the file to save the text to - * - * @return an Output for storing text in a file - */ - public static Output<String, IOException> text( final File file ) - // END SNIPPET: method - { - return text( file, "UTF-8" ); - } - - // START SNIPPET: method - - /** - * Write lines to a text file. Separate each line with a newline ("\n" character). If the writing or sending fails, - * the file is deleted. - * <p> - * If the filename ends with .gz, then the data is automatically GZipped. - * </p> - * @param file the file to save the text to - * - * @return an Output for storing text in a file - */ - public static Output<String, IOException> text( final File file, final String encoding ) - // END SNIPPET: method - { - return new Output<String, IOException>() - { - @Override - @SuppressWarnings( "unchecked" ) - public <SenderThrowableType extends Throwable> void receiveFrom( Sender<? extends String, SenderThrowableType> sender ) - throws IOException, SenderThrowableType - { - File tmpFile = Files.createTemporayFileOf( file ); - - OutputStream stream = new FileOutputStream( tmpFile ); - - // If file should be gzipped, do that automatically - if( file.getName().endsWith( ".gz" ) ) - { - stream = new GZIPOutputStream( stream ); - } - - final BufferedWriter writer = new BufferedWriter( new OutputStreamWriter( stream, encoding ) ); - - try - { - sender.sendTo( new Receiver<String, IOException>() - { - @Override - public void receive( String item ) - throws IOException - { - writer.append( item ).append( '\n' ); - } - } ); - writer.close(); - - // Replace file with temporary file - if( !file.exists() || file.delete() ) - { - if( ! tmpFile.renameTo( file ) ) - { - // TODO: What?? Throw an Exception? - System.err.println( "Unable to rename file: " + tmpFile + " to " + file ); - } - } - } - catch( IOException e ) - { - // We failed writing - close and delete - writer.close(); - if( ! tmpFile.delete() ) - { - System.err.println("Unable to delete temporary file." ); - tmpFile.deleteOnExit(); - } - } - catch( Throwable senderThrowableType ) - { - // We failed writing - close and delete - writer.close(); - if( ! tmpFile.delete() ) - { - System.err.println("Unable to delete temporary file." ); - tmpFile.deleteOnExit(); - } - throw (SenderThrowableType) senderThrowableType; - } - } - }; - } - - // START SNIPPET: method - - /** - * Write lines to a Writer. Separate each line with a newline ("\n" character). - * - * @param writer the Writer to write the text to - * @return an Output for storing text in a Writer - */ - public static Output<String, IOException> text( final Writer writer ) - // END SNIPPET: method - { - return new Output<String, IOException>() - { - - @Override - public <SenderThrowableType extends Throwable> void receiveFrom( Sender<? extends String, SenderThrowableType> sender ) - throws IOException, SenderThrowableType - { - sender.sendTo( new Receiver<String, IOException>() - { - - @Override - public void receive( String item ) - throws IOException - { - writer.append( item ).append( "\n" ); - } - - } ); - } - - }; - } - - // START SNIPPET: method - - /** - * Write lines to a StringBuilder. Separate each line with a newline ("\n" character). - * - * @param builder the StringBuilder to append the text to - * @return an Output for storing text in a StringBuilder - */ - public static Output<String, IOException> text( final StringBuilder builder ) - // END SNIPPET: method - { - return new Output<String, IOException>() - { - - @Override - public <SenderThrowableType extends Throwable> void receiveFrom( Sender<? extends String, SenderThrowableType> sender ) - throws IOException, SenderThrowableType - { - sender.sendTo( new Receiver<String, IOException>() - { - - @Override - public void receive( String item ) - throws IOException - { - builder.append( item ).append( "\n" ); - } - - } ); - } - - }; - } - - // START SNIPPET: method - - /** - * Write ByteBuffer data to a file. If the writing or sending of data fails the file will be deleted. - * - * @param file The destination file. - * - * @return The Output ByteBuffer instance backed by a File. - */ - public static Output<ByteBuffer, IOException> byteBuffer( final File file ) - // END SNIPPET: method - { - return new Output<ByteBuffer, IOException>() - { - @Override - @SuppressWarnings( "unchecked" ) - public <SenderThrowableType extends Throwable> void receiveFrom( Sender<? extends ByteBuffer, SenderThrowableType> sender ) - throws IOException, SenderThrowableType - { - File tmpFile = Files.createTemporayFileOf( file ); - FileOutputStream stream = new FileOutputStream( tmpFile ); - final FileChannel fco = stream.getChannel(); - - try - { - sender.sendTo( new Receiver<ByteBuffer, IOException>() - { - @Override - public void receive( ByteBuffer item ) - throws IOException - { - fco.write( item ); - } - } ); - stream.close(); - - // Replace file with temporary file - if( !file.exists() || file.delete() ) - { - if( ! tmpFile.renameTo( file ) ) - { - // TODO: What can be done in this case? - System.err.println( "Unable to rename file: " + tmpFile + " to " + file ); - } - } - } - catch( IOException e ) - { - // We failed writing - close and delete - stream.close(); - if( ! tmpFile.delete() ) - { - System.err.println("Unable to delete temporary file." ); - tmpFile.deleteOnExit(); - } - - } - catch( Throwable senderThrowableType ) - { - // We failed writing - close and delete - stream.close(); - if( ! tmpFile.delete() ) - { - System.err.println("Unable to delete temporary file." ); - tmpFile.deleteOnExit(); - } - throw (SenderThrowableType) senderThrowableType; - } - } - }; - } - - // START SNIPPET: method - - /** - * Write ByteBuffer data to an OutputStream. - * - * @param stream Destination OutputStream - * - * @return The Output of ByteBuffer that will be backed by the OutputStream. - */ - public static Output<ByteBuffer, IOException> byteBuffer( final OutputStream stream ) - // END SNIPPET: method - { - return new Output<ByteBuffer, IOException>() - { - @Override - public <SenderThrowableType extends Throwable> void receiveFrom( Sender<? extends ByteBuffer, SenderThrowableType> sender ) - throws IOException, SenderThrowableType - { - try - { - sender.sendTo( new Receiver<ByteBuffer, IOException>() - { - @Override - public void receive( ByteBuffer item ) - throws IOException - { - if( item.hasArray() ) - { - stream.write( item.array(), item.arrayOffset(), item.limit() ); - } - else - { - for( int i = 0; i < item.limit(); i++ ) - { - stream.write( item.get( i ) ); - } - } - } - } ); - } - finally - { - stream.close(); - } - } - }; - } - - // START SNIPPET: method - - /** - * Write byte array data to a file. If the writing or sending of data fails the file will be deleted. - * - * @param file The File to be written to. - * @param bufferSize The size of the ByteBuffer. - * - * @return An Output instance that will write to the given File. - */ - public static Output<byte[], IOException> bytes( final File file, final int bufferSize ) - // END SNIPPET: method - { - return new Output<byte[], IOException>() - { - @Override - @SuppressWarnings( "unchecked" ) - public <SenderThrowableType extends Throwable> void receiveFrom( Sender<? extends byte[], SenderThrowableType> sender ) - throws IOException, SenderThrowableType - { - File tmpFile = Files.createTemporayFileOf( file ); - final OutputStream stream = new BufferedOutputStream( new FileOutputStream( tmpFile ), bufferSize ); - - try - { - sender.sendTo( new Receiver<byte[], IOException>() - { - @Override - public void receive( byte[] item ) - throws IOException - { - stream.write( item ); - } - } ); - stream.close(); - - // Replace file with temporary file - if( !file.exists() || file.delete() ) - { - if( ! tmpFile.renameTo( file ) ) - { - // TODO: WHAT??? - System.err.println( "Unable to rename " + tmpFile + " to " + file ); - } - } - } - catch( IOException e ) - { - // We failed writing - close and delete - stream.close(); - if( ! tmpFile.delete() ) - { - System.err.println("Unable to delete temporary file." ); - tmpFile.deleteOnExit(); - } - } - catch( Throwable senderThrowableType ) - { - // We failed writing - close and delete - stream.close(); - if( ! tmpFile.delete() ) - { - System.err.println("Unable to delete temporary file." ); - tmpFile.deleteOnExit(); - } - throw (SenderThrowableType) senderThrowableType; - } - } - }; - } - - // START SNIPPET: method - - /** - * Do nothing. Use this if you have all logic in filters and/or specifications - * - * @param <T> The item type. - * - * @return An Output instance that ignores all data. - */ - public static <T> Output<T, RuntimeException> noop() - // END SNIPPET: method - { - return withReceiver( new Receiver<T, RuntimeException>() - { - @Override - public void receive( T item ) - throws RuntimeException - { - // Do nothing - } - } ); - } - - // START SNIPPET: method - - /** - * Use given receiver as Output. Use this if there is no need to create a "transaction" for each transfer, and no need - * to do batch writes or similar. - * - * @param <T> The item type - * @param receiver receiver for this Output - * - * @return An Output instance backed by a Receiver of items. - */ - public static <T, ReceiverThrowableType extends Throwable> Output<T, ReceiverThrowableType> withReceiver( final Receiver<T, ReceiverThrowableType> receiver ) - // END SNIPPET: method - { - return new Output<T, ReceiverThrowableType>() - { - @Override - public <SenderThrowableType extends Throwable> void receiveFrom( Sender<? extends T, SenderThrowableType> sender ) - throws ReceiverThrowableType, SenderThrowableType - { - sender.sendTo( receiver ); - } - }; - } - - // START SNIPPET: method - - /** - * Write objects to System.out.println. - * - * @return An Output instance that is backed by System.out - */ - public static Output<Object, RuntimeException> systemOut() - // END SNIPPET: method - { - return new Output<Object, RuntimeException>() - { - @Override - public <SenderThrowableType extends Throwable> void receiveFrom( Sender<?, SenderThrowableType> sender ) - throws RuntimeException, SenderThrowableType - { - sender.sendTo( new Receiver<Object, RuntimeException>() - { - @Override - public void receive( Object item ) - { - System.out.println( item ); - } - } ); - } - }; - } - - // START SNIPPET: method - - /** - * Write objects to System.err.println. - * - * @return An Output instance backed by System.in - */ - @SuppressWarnings( "UnusedDeclaration" ) - public static Output<Object, RuntimeException> systemErr() - // END SNIPPET: method - { - return new Output<Object, RuntimeException>() - { - @Override - public <SenderThrowableType extends Throwable> void receiveFrom( Sender<?, SenderThrowableType> sender ) - throws RuntimeException, SenderThrowableType - { - sender.sendTo( new Receiver<Object, RuntimeException>() - { - @Override - public void receive( Object item ) - { - System.err.println( item ); - } - } ); - } - }; - } - - // START SNIPPET: method - - /** - * Add items to a collection - */ - public static <T> Output<T, RuntimeException> collection( final Collection<T> collection ) - // END SNIPPET: method - { - return new Output<T, RuntimeException>() - { - @Override - public <SenderThrowableType extends Throwable> void receiveFrom( Sender<? extends T, SenderThrowableType> sender ) - throws RuntimeException, SenderThrowableType - { - sender.sendTo( new Receiver<T, RuntimeException>() - { - @Override - public void receive( T item ) - throws RuntimeException - { - collection.add( item ); - } - } ); - } - }; - } - - private Outputs() - { - } -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/37ce367a/core/io/src/main/java/org/apache/zest/io/Receiver.java ---------------------------------------------------------------------- diff --git a/core/io/src/main/java/org/apache/zest/io/Receiver.java b/core/io/src/main/java/org/apache/zest/io/Receiver.java deleted file mode 100644 index 2cf94f9..0000000 --- a/core/io/src/main/java/org/apache/zest/io/Receiver.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 org.apache.zest.io; - -/** - * Receiver of items during a specific transfer from an Input to an Output. - */ -// START SNIPPET: receiver -public interface Receiver<T, ReceiverThrowableType extends Throwable> -{ -// END SNIPPET: receiver - /** - * Receive a single item of the given type. The receiver should process it - * and optionally throw an exception if it fails. - * - * @param item - * - * @throws ReceiverThrowableType - */ -// START SNIPPET: receiver - void receive( T item ) - throws ReceiverThrowableType; -} -// END SNIPPET: receiver http://git-wip-us.apache.org/repos/asf/zest-java/blob/37ce367a/core/io/src/main/java/org/apache/zest/io/Sender.java ---------------------------------------------------------------------- diff --git a/core/io/src/main/java/org/apache/zest/io/Sender.java b/core/io/src/main/java/org/apache/zest/io/Sender.java deleted file mode 100644 index 1ebe4d1..0000000 --- a/core/io/src/main/java/org/apache/zest/io/Sender.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 org.apache.zest.io; - -/** - * Sender of items for a particular transfer from an Input to an Output - */ -// START SNIPPET: sender -public interface Sender<T, SenderThrowableType extends Throwable> -{ -// END SNIPPET: sender - /** - * The sender should send all items it holds to the receiver by invoking receiveItem for each item. - * - * If the receive fails it should properly close any open resources. - * - * @param receiver - * @param <ReceiverThrowableType> - * - * @throws ReceiverThrowableType - * @throws SenderThrowableType - */ -// START SNIPPET: sender - <ReceiverThrowableType extends Throwable> void sendTo( Receiver<? super T, ReceiverThrowableType> receiver ) - throws ReceiverThrowableType, SenderThrowableType; -} -// END SNIPPET: sender
