Java tutorial
/******************************************************************************* * Copyright 2011 Danny Kunz * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package org.omnaest.utils.structure.container; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintStream; import java.io.Reader; import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.net.URI; import java.net.URL; import java.net.URLConnection; import java.nio.CharBuffer; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.SerializationUtils; import org.apache.commons.lang3.StringUtils; import org.omnaest.utils.assertion.Assert; import org.omnaest.utils.download.DownloadConnection; import org.omnaest.utils.download.URIHelper; import org.omnaest.utils.download.URLHelper; import org.omnaest.utils.events.exception.ExceptionHandler; import org.omnaest.utils.streams.StreamConnector; /** * This class is a simple container to hold a byte array.<br> * It additionally offers some simple methods to load the byte array from different ways. * * @author Omnaest */ public class ByteArrayContainer { /* ********************************************** Constants ********************************************** */ public final static String ENCODING_UTF8 = "utf-8"; /** UTF-8 */ public final static String DEFAULTENCODING = ENCODING_UTF8; public final static String DEFAULTZIPFILENAME = "data.dat"; /* ********************************************** Variables ********************************************** */ private byte[] content = null; private boolean isContentInvalid = false; /* ********************************************** Beans / Services / References ********************************************** */ private ExceptionHandler exceptionHandler = null; /* ********************************************** Methods ********************************************** */ /** * Default {@link ByteArrayContainer} creating an instance with no content. */ public ByteArrayContainer() { super(); } /** * Creates an {@link ByteArrayContainer} with a copied byte array content. * * @see #copyFrom(byte[]) * @param content */ public ByteArrayContainer(byte[] content) { this(); this.copyFrom(content); } /** * @see #copyFrom(String) * @param content */ public ByteArrayContainer(String content) { this(); this.copyFrom(content); } /** * @see #copyFrom(String, String) * @param content */ public ByteArrayContainer(String content, String encoding) { this(); this.copyFrom(content, encoding); } /** * @see #copyFrom(CharSequence) * @param charsequence */ public ByteArrayContainer(CharSequence charsequence, String encoding) { this(); this.copyFrom(charsequence, encoding); } /** * @param sourceInputStream * @see #copyFrom(InputStream) */ public ByteArrayContainer(InputStream sourceInputStream) { this(); this.copyFrom(sourceInputStream); } /** * @see #copyFrom(CharSequence) * @param charsequence */ public ByteArrayContainer(CharSequence charsequence) { this(); this.copyFrom(charsequence); } /** * @see ByteArrayContainer * @see #copyFrom(Readable) * @param readable */ public ByteArrayContainer(Readable readable) { this(); this.copyFrom(readable); } /** * @return true: content is empty, false: container has content with size > 0 * @see #isNotEmpty() */ public boolean isEmpty() { return (this.content == null || this.content.length == 0); } /** * @see #isEmpty() * @return false: content is empty, true: container has content with size > 0 */ public boolean isNotEmpty() { return !this.isEmpty(); } /** * @see #download(URL) * @param uri */ public void download(URI uri) { this.download(URIHelper.getURLfromURI(uri)); } /** * Downloads the content from the given url resource. * * @see #download(URI) * @see #download(String) * @param url */ public void download(URL url) { if (url != null) { DownloadConnection downloadConnection = new DownloadConnection(); downloadConnection.download(url); this.copyFrom(downloadConnection.getContentAsBytes()); } else { this.clear(); } } /** * Downloads the content from the given url resource. Ensure the urlStr is encoded correctly and is valid at all. * * @see #download(URI) * @see #download(URL) * @param urlStr */ public void download(String urlStr) { this.download(URLHelper.createURL(urlStr)); } /** * Loads the content of the given file into the container. * * @param file * @deprecated use {@link #copyFrom(File)} instead */ @Deprecated public void load(File file) { this.copyFrom(file); } /** * Copies the content of the given {@link File} into the {@link ByteArrayContainer}. <br> * <br> * If the operation fails the {@link #isContentInvalid()} will return true * * @see #isContentInvalid() * @param file * {@link File} * @return this */ public ByteArrayContainer copyFrom(File file) { // this.setContentInvalid(true); this.clear(); // try { // final FileInputStream fileInputStream = new FileInputStream(file); final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); try { // final BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream); StreamConnector.connect(bufferedInputStream, byteArrayOutputStream); bufferedInputStream.close(); } finally { fileInputStream.close(); byteArrayOutputStream.close(); } // this.content = byteArrayOutputStream.toByteArray(); // this.setContentInvalid(false); } catch (Exception e) { handleException(e); } // return this; } /** * Handles the given {@link Exception} using the internal {@link #exceptionHandler} if the reference is not null * * @param e */ private void handleException(Exception e) { if (this.exceptionHandler != null) { this.exceptionHandler.handleException(e); } } /** * Saves the content of the {@link ByteArrayContainer} to a given {@link File} * * @param file * {@link File} * @deprecated use {@link #writeTo(File)} instead */ @Deprecated public void save(File file) { this.writeTo(file); } /** * Writes the content of the {@link ByteArrayContainer} to the given {@link File} * * @param file * {@link File} */ public void writeTo(File file) { // try { // final OutputStream fileOutputStream = new FileOutputStream(file); try { final BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream); try { bufferedOutputStream.write(this.content); bufferedOutputStream.flush(); } finally { bufferedOutputStream.close(); } fileOutputStream.flush(); } finally { fileOutputStream.close(); } } catch (Exception e) { handleException(e); } } /** * Copies the content from another container into this one. * * @param sourceByteArrayContainer * @return this */ public ByteArrayContainer copyFrom(ByteArrayContainer sourceByteArrayContainer) { this.copyFrom(sourceByteArrayContainer.getInputStream()); return this; } /** * Copies the content from an {@link InputStream} into the {@link ByteArrayContainer} without closing the {@link InputStream} <br> * <br> * If the copy operation fails the content of the {@link ByteArrayContainer} is set to invalid. * * @see #isContentInvalid() * @param sourceInputStream * @return this */ public ByteArrayContainer copyFrom(InputStream sourceInputStream) { // this.isContentInvalid = true; this.clear(); // try { // Assert.isNotNull(sourceInputStream, "sourceInputStream must not be null"); // OutputStream outputStream = this.getOutputStream(); StreamConnector.connect(sourceInputStream, outputStream); outputStream.close(); this.isContentInvalid = false; } catch (Exception e) { this.handleException(e); } // return this; } /** * Uses the given {@link URL#openStream()} to retrieve data which will be available within the {@link ByteArrayContainer} <br> * <br> * If the data cannot be resolved completely the {@link #isContentInvalid()} will return true afterwards. * * @see #isContentInvalid() * @see #copyFrom(InputStream) * @param url * {@link URL} * @return this */ public ByteArrayContainer copyFrom(URL url) { // this.isContentInvalid = true; this.clear(); InputStream sourceInputStream = null; try { Assert.isNotNull(url, "url must not be null"); sourceInputStream = url.openStream(); BufferedInputStream bufferedInputStream = new BufferedInputStream(sourceInputStream); this.copyFrom(bufferedInputStream); bufferedInputStream.close(); this.isContentInvalid = false; } catch (IOException e) { this.handleException(e); } finally { try { sourceInputStream.close(); } catch (Exception e) { this.handleException(e); } } // return this; } /** * Similar to {@link #copyFrom(URL)} * * @param urlConnection * {@link URLConnection} * @return this */ public ByteArrayContainer copyFrom(URLConnection urlConnection) { // this.isContentInvalid = true; this.clear(); // InputStream sourceInputStream = null; try { // Assert.isNotNull(urlConnection, "urlConnection must not be null"); // sourceInputStream = urlConnection.getInputStream(); BufferedInputStream bufferedInputStream = new BufferedInputStream(sourceInputStream); this.copyFrom(bufferedInputStream); bufferedInputStream.close(); // this.isContentInvalid = true; } catch (IOException e) { this.handleException(e); } finally { try { // sourceInputStream.close(); } catch (Exception e) { this.handleException(e); } } // return this; } /** * Copies the content from a {@link Readable} using the {@value #ENCODING_UTF8} encoding * * @param readable * @return this */ public ByteArrayContainer copyFrom(Readable readable) { return this.copyFrom(readable, ENCODING_UTF8); } /** * Copies the content from a {@link Readable} using the given encoding * * @param readable * @param encoding * @return this */ public ByteArrayContainer copyFrom(Readable readable, String encoding) { // this.isContentInvalid = false; if (readable != null) { // encoding = StringUtils.defaultString(encoding, ENCODING_UTF8); // try { // final StringBuffer stringBuffer = new StringBuffer(); final CharBuffer charBuffer = CharBuffer.wrap(new char[1000]); for (int read = 0; read >= 0;) { // charBuffer.clear(); read = readable.read(charBuffer); charBuffer.flip(); if (read > 0) { stringBuffer.append(charBuffer, 0, read); } } this.copyFrom(stringBuffer, encoding); } catch (IOException e) { // this.isContentInvalid = true; // this.handleException(e); } } // return this; } /** * Copies the content of a {@link String} into the {@link ByteArrayContainer}. <br> * <br> * If the copy operation fails the content of the {@link ByteArrayContainer} is set to invalid. * * @see #isContentInvalid() * @param string * @param encoding * @return this */ public ByteArrayContainer copyFrom(String string, String encoding) { // this.isContentInvalid = true; try { final OutputStream outputStream = this.getOutputStream(); try { final OutputStreamWriter osw = new OutputStreamWriter(outputStream, encoding); osw.write(string); osw.close(); this.isContentInvalid = false; } finally { outputStream.close(); } } catch (IOException e) { this.handleException(e); } // return this; } /** * Copies the content of a String into the container. * * @param string * @return this */ public ByteArrayContainer copyFrom(String string) { this.copyFrom(string, DEFAULTENCODING); return this; } /** * Copies the content of a {@link CharSequence} into the {@link ByteArrayContainer} using the {@value #DEFAULTENCODING}. * * @param charSequence * @return this */ public ByteArrayContainer copyFrom(CharSequence charSequence) { this.copyFrom(charSequence, DEFAULTENCODING); return this; } /** * Copies the content of a {@link CharSequence} into the {@link ByteArrayContainer}. * * @param charSequence * @param encoding * @return this */ public ByteArrayContainer copyFrom(CharSequence charSequence, String encoding) { this.copyFrom(charSequence.toString(), DEFAULTENCODING); return this; } /** * Copies the content from a byte array into the container. The data is copied and not the given byte array is used. * * @param source * @return this */ public ByteArrayContainer copyFrom(byte[] source) { // ByteArrayInputStream bis = new ByteArrayInputStream(source); this.copyFrom(bis); // return this; } /** * Serializes any given {@link Serializable} element and stores it * * @see #toDeserializedElement() * @param element * @return this */ public <S extends Serializable> ByteArrayContainer copyFromAsSerialized(S element) { final byte[] content = element != null ? SerializationUtils.serialize(element) : null; this.setContent(content); return this; } /** * Deserializes the content into an element * * @see #copyFromAsSerialized(Serializable) * @return new element instance */ @SuppressWarnings("unchecked") public <S extends Serializable> S toDeserializedElement() { return this.content != null ? (S) SerializationUtils.deserialize(this.content) : null; } /** * Transforms the content into a String. As default utf-8 is used. * * @see #toString(String) */ public String toString() { return this.toString(DEFAULTENCODING); } /** * Transforms the content into a String. * * @see #toString() * @param encoding * specifies the encoding of the binary data. Example: "utf-8" * @return String, null if error happens */ public String toString(String encoding) { // String retval = null; // try { StringBuffer sb = new StringBuffer(); StreamConnector.connect(this.getInputStream(), sb, encoding); retval = sb.toString(); } catch (IOException e) { this.handleException(e); } // return retval; } /** * Returns the content as a list of strings, separated by line feed and/or carriage return. The default encoding "utf-8" is * used. * * @return */ public List<String> toStringList() { return this.toStringList(DEFAULTENCODING); } /** * Returns the content as a list of strings, separated by line feed and/or carriage return. * * @param encoding * : for example = "utf-8" * @return */ public List<String> toStringList(String encoding) { // final String regExDelimiter = "[\r\n]+"; return this.toStringList(encoding, regExDelimiter); } /** * Returns the content as a list of strings, separated by an arbitrary regular expression. * * @param encoding * : for example = "utf-8" * @see #ENCODING_UTF8 * @return */ public List<String> toStringList(String encoding, String regExDelimiter) { // List<String> retlist = new ArrayList<String>(); // String content = this.toString(encoding); // final String tokenDelimiter = "}>|<{"; content = content.replaceAll(regExDelimiter, tokenDelimiter); String[] lines = StringUtils.splitByWholeSeparatorPreserveAllTokens(content, tokenDelimiter); CollectionUtils.addAll(retlist, lines); // return retlist; } /** * Writes the content of the {@link ByteArrayContainer} to the given {@link Writer} instance. The {@link Writer#flush()} method * will be invoked afterwards but it will not be closed. * * @see #writeTo(Writer) * @param writer * @param encoding * @return true, if no error occurs */ public boolean writeTo(Writer writer, String encoding) { // boolean retval = true; // if (writer != null) { try { writer.write(this.toString(encoding)); writer.flush(); } catch (IOException e) { retval = false; this.handleException(e); } } // return retval; } /** * Similar to {@link #writeTo(Writer, String)} using the default encoding {@value #ENCODING_UTF8} * * @see #writeTo(Writer, String) * @param writer * @return true, if no error occurs */ public boolean writeTo(Writer writer) { return this.writeTo(writer, ENCODING_UTF8); } /** * Writes the content of the {@link ByteArrayContainer} to an {@link Appendable} e.g. a {@link StringBuilder} or * {@link StringBuffer} * * @param appendable * @param encoding * @return true : transfer successful */ public boolean writeTo(Appendable appendable, String encoding) { // boolean retval = true; // try { StringBuffer sb = new StringBuffer(); StreamConnector.connect(this.getInputStream(), sb, encoding); // appendable.append(sb); } catch (IOException e) { retval = false; this.handleException(e); } // return retval; } /** * Writes the content of the {@link ByteArrayContainer} to a given {@link OutputStream} without closing the {@link OutputStream} * but flushing the content to it. * * @param outputStream * @return true : transfer was successful */ public boolean writeTo(OutputStream outputStream) { return StreamConnector.transfer(this.getInputStream(), outputStream).isSuccessful(); } /** * Clears the content. */ public void clear() { this.setContent(null); } /** * @return */ public byte[] getContent() { return this.content; } /** * @param content * @return */ public ByteArrayContainer setContent(byte[] content) { this.content = content; return this; } /** * @return */ public InputStream getInputStream() { InputStream is = null; if (this.content != null) { is = new ByteArrayInputStream(this.content); } return is; } /** * Returns a {@link Reader} with the default encoding {@value #DEFAULTENCODING} * * @return */ public Reader getReader() { return this.getReader(DEFAULTENCODING); } /** * Returns a {@link Reader} using the given encoing * * @param encoding * @return */ public Reader getReader(String encoding) { Reader retval = null; try { retval = new InputStreamReader(this.getInputStream(), encoding); } catch (UnsupportedEncodingException e) { this.handleException(e); } return retval; } /** * Returns an outputstream, that allows to write the byte array content directly.<br> * Be aware of the fact, that the content is written only if the outputstream is closed correctly! * * @return */ public OutputStream getOutputStream() { return new ByteArrayOutputStream(0) { @Override public void close() { try { super.close(); } catch (IOException e) { if (ByteArrayContainer.this.exceptionHandler != null) { ByteArrayContainer.this.exceptionHandler.handleException(e); } } ByteArrayContainer.this.content = this.toByteArray(); } @Override public void flush() throws IOException { super.flush(); ByteArrayContainer.this.content = this.toByteArray(); } }; } /** * Returns an {@link OutputStreamWriter} using the given encoding * * @param encoding * @return */ public OutputStreamWriter getOutputStreamWriter(String encoding) { // OutputStreamWriter retval = null; // try { retval = new OutputStreamWriter(this.getOutputStream(), encoding); } catch (Exception e) { handleException(e); } // return retval; } /** * Like {@link #getOutputStreamWriter(String)} using the {@link #DEFAULTENCODING} * * @see #getOutputStreamWriter(String) * @return */ public OutputStreamWriter getOutputStreamWriter() { return this.getOutputStreamWriter(DEFAULTENCODING); } /** * Converts the content into a zip file content. For example, load a file content, call this method, and save the content back * to the same file, to make the file zipped. */ public void zip(String zipFileName) { if (StringUtils.isNotBlank(zipFileName)) { // final Map<String, ByteArrayContainer> byteArrayContainerMap = new HashMap<String, ByteArrayContainer>(); byteArrayContainerMap.put(zipFileName, this); ByteArrayContainer tempByteArrayContainer = ByteArrayContainer .zipFilenameByteArrayContainerMap(byteArrayContainerMap); if (tempByteArrayContainer != null) { this.content = tempByteArrayContainer.content; } } } /** * @see #zip(String) */ public void zip() { this.zip(ByteArrayContainer.generateRandomDefaultFileName()); } /** * Zipps all ByteArrayContainers of a given map, which contains filenames with corresponding unzipped ByteArrayContainer * objects. * * @param byteArrayContainerMap */ public static ByteArrayContainer zipFilenameByteArrayContainerMap( Map<String, ByteArrayContainer> byteArrayContainerMap) { // final ExceptionHandler exceptionHandler = null; return zipFilenameByteArrayContainerMap(byteArrayContainerMap, exceptionHandler); } /** * Zipps all ByteArrayContainers of a given map, which contains filenames with corresponding unzipped ByteArrayContainer * objects. * * @param byteArrayContainerMap * @param exceptionHandler * {@link ExceptionHandler} */ public static ByteArrayContainer zipFilenameByteArrayContainerMap( Map<String, ByteArrayContainer> byteArrayContainerMap, ExceptionHandler exceptionHandler) { // ByteArrayContainer zippedBac = new ByteArrayContainer(); try { // ZipOutputStream zos = new ZipOutputStream(zippedBac.getOutputStream()); // for (String iFilename : byteArrayContainerMap.keySet()) { // ByteArrayContainer sourceByteArrayContainer = byteArrayContainerMap.get(iFilename); // if (StringUtils.isNotBlank(iFilename) && sourceByteArrayContainer != null && sourceByteArrayContainer.isNotEmpty()) { ZipEntry zipEntry = new ZipEntry(iFilename); zos.putNextEntry(zipEntry); StreamConnector.connect(sourceByteArrayContainer.getInputStream(), zos); } } zos.close(); } catch (Exception e) { if (exceptionHandler != null) { exceptionHandler.handleException(e); } } // return zippedBac; } /** * Generates a random filename basing on the zip default filename and a random number. * * @return */ private static String generateRandomDefaultFileName() { return DEFAULTZIPFILENAME + String.valueOf(System.currentTimeMillis()) + String.valueOf(Math.round(Math.random() * 1000000000l)); } /** * Converts a zip file content into unzipped content. For example load a zip file, and call this method, to get the unzipped * content of the file. If an error occurs, the content will be set to null, and null will be returned. <br> * <br> * Ensure the zip file contains only one file, if you wanna use the current ByteArrayContainer obejct. Only the first file is * read for the current container, all others are only saved within the returned map. * * @see #unzipIntoFilenameByteArrayContainerMap(ByteArrayContainer) * @return Map of the zip file names with unzipped ByteArrayContainer objects, or null, if unzipping was unsuccesful. */ public Map<String, ByteArrayContainer> unzip() { // Map<String, ByteArrayContainer> retmap = ByteArrayContainer.unzipIntoFilenameByteArrayContainerMap(this); // if (retmap != null && retmap.size() > 0) { this.content = null; this.copyFrom(retmap.values().iterator().next()); } else { this.content = null; } // return retmap; } /** * Unzipps the given ByteArrayContainer object into a map containing the filenames and unzipped ByteArrayContainer objects for * each file. * * @param byteArrayContainer * @return */ public static Map<String, ByteArrayContainer> unzipIntoFilenameByteArrayContainerMap( ByteArrayContainer byteArrayContainer) { final ExceptionHandler exceptionHandler = null; return unzipIntoFilenameByteArrayContainerMap(byteArrayContainer, exceptionHandler); } /** * Unzipps the given ByteArrayContainer object into a map containing the filenames and unzipped ByteArrayContainer objects for * each file. * * @param byteArrayContainer * @param exceptionHandler * {@link ExceptionHandler} * @return */ public static Map<String, ByteArrayContainer> unzipIntoFilenameByteArrayContainerMap( ByteArrayContainer byteArrayContainer, ExceptionHandler exceptionHandler) { // Map<String, ByteArrayContainer> retmap = new LinkedHashMap<String, ByteArrayContainer>(); // try { // ZipInputStream zis = new ZipInputStream(byteArrayContainer.getInputStream()); // for (ZipEntry zipEntry = zis.getNextEntry(); zipEntry != null; zipEntry = zis.getNextEntry()) { ByteArrayContainer unzippedBac = new ByteArrayContainer(); StreamConnector.connect(zis, unzippedBac.getOutputStream()); retmap.put(zipEntry.getName(), unzippedBac); } } catch (IOException e) { if (exceptionHandler != null) { exceptionHandler.handleException(e); } } // return retmap; } /* ********************************************** STATIC FACTORY METHOD PART ********************************************** */ /** * Used by the factory method. * * @see #createNewInstance */ public static Class<? extends ByteArrayContainer> implementationForByteArrayContainerClass = ByteArrayContainer.class; /** * Creates a new instance of this class. * * @see #implementationForByteArrayContainerClass */ public static ByteArrayContainer createNewInstance() { ByteArrayContainer result = null; try { result = ByteArrayContainer.implementationForByteArrayContainerClass.newInstance(); } catch (Exception e) { } return result; } /** * Returns true if a previous operation on the {@link ByteArrayContainer} has put the content into a malformed state. * * @see #copyFrom(InputStream) * @see #copyFrom(String) * @return */ public boolean isContentInvalid() { return this.isContentInvalid; } /** * Sets the content of the {@link ByteArrayContainer} to be marked as invalid * * @param isContentInvalid */ public void setContentInvalid(boolean isContentInvalid) { this.isContentInvalid = isContentInvalid; } /** * Returns a new {@link PrintStream} using the {@value #DEFAULTENCODING} encoding * * @see PrintStream * @return */ public PrintStream getPrintStreamWriter() { // return this.getPrintStreamWriter(DEFAULTENCODING); } /** * Returns a new {@link PrintStream} * * @see PrintStream * @param encoding * @return */ public PrintStream getPrintStreamWriter(String encoding) { // boolean autoFlush = true; return this.getPrintStreamWriter(encoding, autoFlush); } /** * Returns a new {@link PrintStream} * * @see PrintStream * @param encoding * @param autoFlush * @return */ public PrintStream getPrintStreamWriter(String encoding, boolean autoFlush) { // PrintStream retval = null; // final OutputStream outputStream = this.getOutputStream(); try { retval = new PrintStream(outputStream, autoFlush, encoding); } catch (UnsupportedEncodingException e) { this.handleException(e); } // return retval; } /** * @param exceptionHandler * {@link ExceptionHandler} * @return this */ public ByteArrayContainer setExceptionHandler(ExceptionHandler exceptionHandler) { // this.exceptionHandler = exceptionHandler; return this; } /** * Returns a new {@link ByteArrayContainer} instance mapping the same byte[] array as the given {@link ByteArrayContainer} * * @param byteArrayContainer * @return new instance */ public static ByteArrayContainer valueOf(ByteArrayContainer byteArrayContainer) { final ByteArrayContainer retval = new ByteArrayContainer(); if (byteArrayContainer != null) { retval.setContent(byteArrayContainer.getContent()); } return retval; } }