diff --git a/.gitignore b/.gitignore
index 8a5dd749d..27c910121 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,5 +32,5 @@ derby.log
dist/
unit-tests.log
/lib/
-src/main/resources/com/intel/chimera/native/
-src/main/resources/com/intel/chimera/native/*
\ No newline at end of file
+dependency-reduced-pom.xml
+conf/benchmark.properties
diff --git a/conf/benchmark.properties.template b/conf/benchmark.properties.template
new file mode 100644
index 000000000..53bbc94dd
--- /dev/null
+++ b/conf/benchmark.properties.template
@@ -0,0 +1,24 @@
+#
+# 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.
+#
+warmupIterations 1000
+iterations 1000
+dataSize 1073741824
+operationSize 8192
+
+bufferSize 20
+cipherClasses org.apache.commons.crypto.cipher.OpensslCipher,org.apache.commons.crypto.cipher.JceCipher
+transformations AES/CTR/NoPadding,AES/CBC/NoPadding
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 479e3b053..231f4154d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -138,6 +138,8 @@ http://maven.apache.org/maven-v4_0_0.xsd">
CRYPTO
12320024
true
+ 1.6
+ 2.4.3
@@ -332,6 +334,22 @@ http://maven.apache.org/maven-v4_0_0.xsd">
org.apache.maven.plugins
maven-compiler-plugin
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ ${maven-shade-plugin.version}
+
+
+
+
+
+ package
+
+ shade
+
+
+
+
diff --git a/sbin/run-benchmark.sh b/sbin/run-benchmark.sh
new file mode 100644
index 000000000..513b5bf50
--- /dev/null
+++ b/sbin/run-benchmark.sh
@@ -0,0 +1,35 @@
+#
+# 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.
+#
+#!/bin/bash
+set -x
+if [ "$#" -ne 2 ];then
+ echo "Usage: sh run-benchmark.sh path/to/JDKwithoutAESNIsupport path/to/JDKwithAESNIsupport \n JDK7u45 or higher supports AES-NI."
+ exit 1
+fi
+echo "This benchmark will evaluate the performance of Chimera in different transfomations, ciphers and JDK versions"
+
+if [ ! -f "conf/benchmark.properties" ];then
+ echo "Not able to find the benchmark.propety, will use default propety instead"
+ cp conf/benchmark.properties.template conf/benchmark.properties
+fi
+
+CRYPTO_JAR=`find . -name commons-crypto*.jar`
+
+echo "Using JDK in path $1 to evalue the performance"
+$1/bin/java -Djava.library.path="$PATH" -cp $CRYPTO_JAR:target/test-classes org.apache.commons.crypto.benchmark.CommonsCryptoBenchmark conf/benchmark.properties
+echo "Using JDK in path $2 to evaluate the performance"
+$2/bin/java -Djava.library.path="$PATH" -cp $CRYPTO_JAR:target/test-classes org.apache.commons.crypto.benchmark.CommonsCryptoBenchmark conf/benchmark.properties
diff --git a/src/test/java/org/apache/commons/crypto/benchmark/CommonsCryptoBenchmark.java b/src/test/java/org/apache/commons/crypto/benchmark/CommonsCryptoBenchmark.java
new file mode 100644
index 000000000..cad82bb9f
--- /dev/null
+++ b/src/test/java/org/apache/commons/crypto/benchmark/CommonsCryptoBenchmark.java
@@ -0,0 +1,121 @@
+/**
+ * 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.commons.crypto.benchmark;
+
+import org.apache.commons.crypto.benchmark.option.BenchmarkOption;
+import org.apache.commons.crypto.benchmark.option.StreamOption;
+import org.apache.commons.crypto.cipher.CipherTransformation;
+
+import java.io.*;
+import java.util.Properties;
+
+public class CommonsCryptoBenchmark {
+ static String defaultConfigPath = "./conf/benchmark.properties";
+
+ public static void main(String[] args) throws IOException {
+ Properties prop = new Properties();
+ String propFileName = "benchmark.properties";
+
+ if (args != null && args.length != 0 && args.length != 1 && args.length != 4) {
+ System.out.println(
+ "Usage: java -Djava.library.path=\"$PATH\" -cp path/to/commons-crypto-[version].jar:path/to/target/test-classes/ org.apache.commons.crypto.benchmark.CommonsCryptoBenchmark [warmupIterations] [iterations] [dataSize] [operationSize] or java -Djava.library.path=\"$PATH\" -cp commons-crypto-[version].jar:path/to/Chimera/target/test-classes/ org.apache.commons.crypto.benchmark.CommonsCryptoBenchmark [path/to/configuration]");
+ System.out.println("args[0]: " + args[0]);
+ System.exit(1);
+ }
+
+ String confFilePath = defaultConfigPath;
+ if (args.length == 1) {
+ System.out
+ .println("Use configurations specified by a configuration file.");
+ confFilePath = args[0];
+ }
+
+ File configFile = new File(confFilePath);
+ InputStream inputStream;
+
+ if (args.length == 0 || args.length == 1) {
+ if (configFile.exists()) {
+ inputStream = new FileInputStream(configFile);
+ } else {
+ System.out.println(
+ "can not find the configuration file under the current path");
+ inputStream = CommonsCryptoBenchmark.class.getClassLoader()
+ .getResourceAsStream(propFileName);
+ }
+ prop.load(inputStream);
+ }
+
+ // Benchmark related configurations
+ BenchmarkOption.CipherBenchmarkOptionBuilder cipherBenchmarkOptionBuilder
+ = BenchmarkOption.newBuilder();
+ if(args.length == 1){
+ if (prop.containsKey("warmupIterations")) {
+ cipherBenchmarkOptionBuilder.buildWarmupIterations(Integer
+ .parseInt(prop.getProperty("warmupIterations")));
+ }
+ if (prop.containsKey("iterations")) {
+ cipherBenchmarkOptionBuilder.buildIterations(Integer
+ .parseInt(prop.getProperty("iterations")));
+ }
+ if (prop.containsKey("dataSize")) {
+ cipherBenchmarkOptionBuilder.buildDataSize(Integer.parseInt(
+ prop.getProperty("dataSize")));
+ }
+ if (prop.containsKey("operationSize")) {
+ cipherBenchmarkOptionBuilder.buildOperationSize(Integer
+ .parseInt(prop.getProperty("operationSize")));
+ }
+ }else{
+ // specify by cmd
+ cipherBenchmarkOptionBuilder.buildWarmupIterations(Integer
+ .parseInt(args[0]));
+ cipherBenchmarkOptionBuilder.buildIterations(Integer
+ .parseInt(args[1]));
+ cipherBenchmarkOptionBuilder.buildDataSize(Integer
+ .parseInt(args[2]));
+ cipherBenchmarkOptionBuilder.buildOperationSize(Integer
+ .parseInt(args[3]));
+ }
+
+ BenchmarkOption benchmarkOption = cipherBenchmarkOptionBuilder.create();
+
+ System.out.println("current benchmarkOption option is " + benchmarkOption);
+ // Stream related configuration
+ String transformations = (prop.contains("transformations")) ? prop
+ .getProperty(
+ "transformations") : ("AES/CTR/NoPadding,AES/CBC/NoPadding");
+ String cipherClazzNames = (prop.contains("cipherClasses")) ? prop
+ .getProperty("cipherClasses") : ("org.apache.commons.crypto.cipher" +
+ ".OpensslCipher,org.apache.commons.crypto.cipher.JceCipher");
+ int bufferSize = (prop.containsKey("bufferSize")) ? Integer
+ .parseInt(prop.getProperty("bufferSize")) : (512 * 1024);
+ for (String t : transformations.split(",")) {
+ for(String c : cipherClazzNames.split(",")){
+ CipherTransformation transformation = CipherTransformation.fromName(t);
+ StreamOption streamOption = StreamOption.newBuilder()
+ .setBufferSize(bufferSize)
+ .setCipherTransformation(transformation)
+ .setCipherClazzName(c).build();
+ System.out.println("current stream option is " + streamOption);
+ CryptoStreamBenchmark cryptoStreamBenchmark = new CryptoStreamBenchmark(
+ benchmarkOption, streamOption);
+ cryptoStreamBenchmark.getBenchMarkData();
+ }
+ }
+ }
+}
diff --git a/src/test/java/org/apache/commons/crypto/benchmark/CryptoStreamBenchmark.java b/src/test/java/org/apache/commons/crypto/benchmark/CryptoStreamBenchmark.java
new file mode 100644
index 000000000..e274e403a
--- /dev/null
+++ b/src/test/java/org/apache/commons/crypto/benchmark/CryptoStreamBenchmark.java
@@ -0,0 +1,211 @@
+/**
+ * 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.commons.crypto.benchmark;
+
+import org.apache.commons.crypto.benchmark.option.BenchmarkOption;
+import org.apache.commons.crypto.benchmark.option.StreamOption;
+import org.apache.commons.crypto.conf.ConfigurationKeys;
+import org.apache.commons.crypto.stream.CryptoInputStream;
+import org.apache.commons.crypto.stream.CryptoOutputStream;
+
+import java.io.*;
+import java.util.Calendar;
+import java.util.Properties;
+import java.util.Random;
+import java.util.TimeZone;
+
+public class CryptoStreamBenchmark {
+ protected String benchMarkName;
+ protected BenchmarkOption benchmarkOption;
+ protected StreamOption streamOption;
+ byte[] inputData;
+ CryptoInputStream cryptoInputStream;
+ OutputStream cryptoOutputStream;
+ ByteArrayInputStream inputStream;
+ ByteArrayOutputStream outputStream;
+
+ public CryptoStreamBenchmark(BenchmarkOption benchmarkOption,
+ StreamOption streamOption) {
+ this.benchmarkOption = benchmarkOption;
+ this.streamOption = streamOption;
+ outputStream = new ByteArrayOutputStream(benchmarkOption.dataSize);
+ inputData = prepareData(benchmarkOption.dataSize);
+ inputStream = new ByteArrayInputStream(inputData);
+ benchMarkName = "Benchmark test using " + streamOption
+ .getCipherClazzName() + " in transformation " + streamOption
+ .getTransformation();
+ }
+
+ OutputStream getCryptoOutputStream() throws IOException {
+ if (cryptoOutputStream == null) {
+ Random r = new Random();
+ byte[] iv = new byte[16];
+ byte[] key = new byte[16];
+ r.nextBytes(iv);
+ r.nextBytes(key);
+
+ Properties props = new Properties();
+ props.put(ConfigurationKeys.CHIMERA_CRYPTO_CIPHER_CLASSES_KEY,
+ streamOption.getCipherClazzName());
+ props.put(ConfigurationKeys.CHIMERA_CRYPTO_STREAM_BUFFER_SIZE_KEY,
+ streamOption.getBufferSize());
+ cryptoOutputStream = new CryptoOutputStream(
+ streamOption.getTransformation(), props, outputStream, key, iv);
+ }
+ return cryptoOutputStream;
+ }
+
+ protected InputStream getCryptoInputStream() throws IOException {
+ if (cryptoInputStream == null) {
+ Random r = new Random();
+ byte[] iv = new byte[16];
+ byte[] key = new byte[16];
+ r.nextBytes(iv);
+ r.nextBytes(key);
+
+ Properties props = new Properties();
+ props.put(ConfigurationKeys.CHIMERA_CRYPTO_CIPHER_CLASSES_KEY,
+ streamOption.getCipherClazzName());
+ props.put(ConfigurationKeys.CHIMERA_CRYPTO_STREAM_BUFFER_SIZE_KEY,
+ streamOption.getBufferSize());
+ cryptoInputStream = new CryptoInputStream(
+ streamOption.getTransformation(), props, inputStream, key, iv);
+ }
+ return cryptoInputStream;
+ }
+
+ protected byte[] prepareData(int size) {
+ byte[] data = new byte[size];
+ Random r = new Random();
+ r.nextBytes(data);
+ return data;
+ }
+
+ public void testEncryption(int iterations) {
+ try {
+ OutputStream cryptoOutputStream = getCryptoOutputStream();
+
+ System.out.println("warming up");
+ // warm up
+ for (int i = 0; i < benchmarkOption.warmupIterations; i++) {
+ doWriteOperation(outputStream, cryptoOutputStream, inputData);
+ }
+
+ System.out.println("warming up complete.");
+
+ long begin = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
+ .getTimeInMillis();
+ for (int i = 0; i < iterations; i++) {
+ doWriteOperation(outputStream, cryptoOutputStream, inputData);
+ }
+
+ long end = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
+ .getTimeInMillis();
+ printResult("===encryption",
+ 1000.0 * benchmarkOption.dataSize * iterations / ((end - begin) *
+ 1024.0 * 1024.0));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void testDecryption(int iterations) {
+ try {
+ InputStream cryptoInputStream = getCryptoInputStream();
+
+ byte[] outputData = new byte[benchmarkOption.dataSize];
+
+ System.out.println("Warming up.");
+ // warm up
+ for (int i = 0; i < benchmarkOption.warmupIterations; i++) {
+ doReadOperation(inputStream, cryptoInputStream, outputData);
+ }
+
+ System.out.println("warming up complete.");
+ long begin = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
+ .getTimeInMillis();
+
+ for (int i = 0; i < iterations; i++) {
+ doReadOperation(inputStream, cryptoInputStream, outputData);
+ }
+
+ long end = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
+ .getTimeInMillis();
+ printResult("=== decryption",
+ 1000.0 * benchmarkOption.dataSize * iterations / ((end - begin) *
+ 1024.0 * 1024.0));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void doWriteOperation(ByteArrayOutputStream outputStream,
+ OutputStream cryptoOutputStream, byte[] inputData)
+ throws IOException {
+ int offset = 0;
+ int remaining = benchmarkOption.dataSize;
+ while (remaining > 0) {
+ int len = (benchmarkOption.operationSize < remaining) ?
+ benchmarkOption.operationSize : remaining;
+ cryptoOutputStream.write(inputData, offset, len);
+ offset += len;
+ remaining -= len;
+ }
+ outputStream.reset();
+ }
+
+ private void doReadOperation(ByteArrayInputStream inputStream,
+ InputStream cryptoInputStream, byte[] outputData)
+ throws IOException {
+ int remaining = benchmarkOption.dataSize;
+ int offset = 0;
+ while (remaining > 0) {
+ int len = (remaining < benchmarkOption.operationSize) ? remaining :
+ benchmarkOption.operationSize;
+ int v = cryptoInputStream.read(outputData, offset, len);
+ offset += v;
+ remaining -= v;
+ }
+ inputStream.reset();
+ }
+
+ public void getBenchMarkData() {
+ System.out.println();
+ System.out.println(getBenchMarkName() + " begins!");
+ System.out.println("Encryption starts.");
+ testEncryption(benchmarkOption.iterations);
+ System.out.println("Encryption ends.");
+
+ System.out.println("Decryption starts.");
+ testDecryption(benchmarkOption.iterations);
+ System.out.println("Decryption ends.");
+ System.out.println(getBenchMarkName() + " ends!");
+ System.out.println();
+ }
+
+ protected String getBenchMarkName() {
+ return benchMarkName;
+ }
+
+ protected void printResult(String operation, double timeCost) {
+ System.out.println(
+ "result of " + getBenchMarkName() + " for the " + operation + " operation is " + timeCost +
+ " M/s");
+ System.out.println();
+ }
+}
diff --git a/src/test/java/org/apache/commons/crypto/benchmark/option/BenchmarkOption.java b/src/test/java/org/apache/commons/crypto/benchmark/option/BenchmarkOption.java
new file mode 100644
index 000000000..2879b0c0d
--- /dev/null
+++ b/src/test/java/org/apache/commons/crypto/benchmark/option/BenchmarkOption.java
@@ -0,0 +1,83 @@
+/**
+ * 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.commons.crypto.benchmark.option;
+
+public class BenchmarkOption {
+ public int dataSize;
+ public int operationSize;
+ public int warmupIterations;
+ public int iterations;
+
+ private BenchmarkOption() {
+ }
+
+ private BenchmarkOption(int dataSize, int operationSize,
+ int warmupIterations, int iterations) {
+ this.dataSize = dataSize;
+ this.operationSize = operationSize;
+ this.warmupIterations = warmupIterations;
+ this.iterations = iterations;
+ }
+
+ public static CipherBenchmarkOptionBuilder newBuilder() {
+ return new CipherBenchmarkOptionBuilder();
+ }
+
+ public String toString() {
+ return "dataSize is " + dataSize + " operationSize is " + operationSize +
+ " warmupIterations is " + warmupIterations + " iterations is " +
+ iterations;
+ }
+
+ public static class CipherBenchmarkOptionBuilder {
+ public static final int DEFAULT_DATASIZE = 1073741824;
+ public static final int DEFAULT_OPERATIONSIZE = 8192;
+ public static final int DEFAULT_WARMUPITERATIONS = 1000;
+ public static final int DEFAULT_ITERATIONS = 1000;
+ public int dataSize = DEFAULT_DATASIZE;
+ public int operationSize = DEFAULT_OPERATIONSIZE;
+ public int warmupIterations = DEFAULT_WARMUPITERATIONS;
+ public int iterations = DEFAULT_ITERATIONS;
+
+ public CipherBenchmarkOptionBuilder buildDataSize(int dataSize) {
+ this.dataSize = dataSize;
+ return this;
+ }
+
+ public CipherBenchmarkOptionBuilder buildOperationSize(int operationSize) {
+ this.operationSize = operationSize;
+ return this;
+ }
+
+ public CipherBenchmarkOptionBuilder buildWarmupIterations(
+ int warmupIterations) {
+ this.warmupIterations = warmupIterations;
+ return this;
+ }
+
+ public CipherBenchmarkOptionBuilder buildIterations(int iterations) {
+ this.iterations = iterations;
+ return this;
+ }
+
+ public BenchmarkOption create() {
+ return new BenchmarkOption(dataSize, operationSize, warmupIterations,
+ iterations);
+ }
+ }
+}
diff --git a/src/test/java/org/apache/commons/crypto/benchmark/option/StreamOption.java b/src/test/java/org/apache/commons/crypto/benchmark/option/StreamOption.java
new file mode 100644
index 000000000..af2cdfc9f
--- /dev/null
+++ b/src/test/java/org/apache/commons/crypto/benchmark/option/StreamOption.java
@@ -0,0 +1,95 @@
+/**
+ * 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.commons.crypto.benchmark.option;
+
+import org.apache.commons.crypto.cipher.CipherTransformation;
+
+public class StreamOption {
+
+ private CipherTransformation transformation;
+ private String cipherClazzName;
+ private int bufferSize;
+
+ private StreamOption() {
+ }
+
+ private StreamOption(int bufferSize, CipherTransformation transformation,
+ String cipherClazzName) {
+ this.bufferSize = bufferSize;
+ this.transformation = transformation;
+ this.cipherClazzName = cipherClazzName;
+ }
+
+ public CipherTransformation getTransformation() {
+ return transformation;
+ }
+
+ public void setTransformation(
+ CipherTransformation transformation) {
+ this.transformation = transformation;
+ }
+
+ public int getBufferSize() {
+ return bufferSize;
+ }
+
+ public String getCipherClazzName(){
+ return cipherClazzName;
+ }
+
+ public void setBufferSize(int bufferSize) {
+ this.bufferSize = bufferSize;
+ }
+
+ public String toString() {
+ return "CipherTransformation is " + transformation + " " +
+ "cipherClazzName is " + cipherClazzName + " bufferSize is " +
+ bufferSize;
+ }
+
+ public static StreamOptionBuilder newBuilder() {
+ return new StreamOptionBuilder();
+ }
+
+ public static class StreamOptionBuilder {
+ private static final int DEFAULT_BUFFERSIZE = 512 * 1024;
+ private CipherTransformation transformation;
+ private int bufferSize = DEFAULT_BUFFERSIZE;
+ private String cipherClazzName;
+
+ public StreamOptionBuilder setBufferSize(int bufferSize) {
+ this.bufferSize = bufferSize;
+ return this;
+ }
+
+ public StreamOptionBuilder setCipherTransformation(
+ CipherTransformation transformation) {
+ this.transformation = transformation;
+ return this;
+ }
+
+ public StreamOptionBuilder setCipherClazzName(String cipherClazzName){
+ this.cipherClazzName = cipherClazzName;
+ return this;
+ }
+
+ public StreamOption build() {
+ return new StreamOption(bufferSize, transformation, cipherClazzName);
+ }
+ }
+}