/*
*
* Copyright (c) 2013 - 2017 Lijun Liao
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License version 3
* as published by the Free Software Foundation with the addition of the
* following permission added to Section 15 as permitted in Section 7(a):
*
* FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
* THE AUTHOR LIJUN LIAO. LIJUN LIAO DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
* OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License.
*
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial activities involving the XiPKI software without
* disclosing the source code of your own applications.
*
* For more information, please contact Lijun Liao at this
* address: lijun.liao@gmail.com
*/
package org.xipki.commons.common.util;
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.OutputStream;
import java.net.HttpURLConnection;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URL;
import java.net.URLConnection;
import java.net.UnknownHostException;
import java.util.Base64;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Lijun Liao
* @since 2.0.0
*/
public class IoUtil {
private static final Logger LOG = LoggerFactory.getLogger(IoUtil.class);
private IoUtil() {
}
public static void closeStream(final OutputStream stream) {
if (stream == null) {
return;
}
try {
stream.close();
} catch (Throwable th) {
LOG.error("could not close stream: {}", th.getMessage());
}
}
public static byte[] read(final String fileName) throws IOException {
return read(new File(expandFilepath(fileName)));
}
public static byte[] read(final File file) throws IOException {
return read(new FileInputStream(expandFilepath(file)));
}
public static byte[] read(final InputStream in) throws IOException {
try {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
int readed = 0;
byte[] buffer = new byte[2048];
while ((readed = in.read(buffer)) != -1) {
bout.write(buffer, 0, readed);
}
return bout.toByteArray();
} finally {
try {
in.close();
} catch (IOException ex) {
LOG.error("could not close stream: {}", ex.getMessage());
}
}
}
public static void save(final String fileName, final byte[] encoded) throws IOException {
save(new File(expandFilepath(fileName)), encoded);
}
public static void save(final File file, final byte[] content) throws IOException {
File tmpFile = expandFilepath(file);
File parent = tmpFile.getParentFile();
if (parent != null && !parent.exists()) {
parent.mkdirs();
}
FileOutputStream out = new FileOutputStream(tmpFile);
try {
out.write(content);
} finally {
out.close();
}
}
public static String getHostAddress() throws SocketException {
List<String> addresses = new LinkedList<>();
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface ni = interfaces.nextElement();
Enumeration<InetAddress> ee = ni.getInetAddresses();
while (ee.hasMoreElements()) {
InetAddress ia = ee.nextElement();
if (ia instanceof Inet4Address) {
addresses.add(ia.getHostAddress());
}
}
}
for (String addr : addresses) {
if (!addr.startsWith("192.") && !addr.startsWith("127.")) {
return addr;
}
}
for (String addr : addresses) {
if (!addr.startsWith("127.")) {
return addr;
}
}
if (addresses.size() > 0) {
return addresses.get(0);
} else {
try {
return InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException ex) {
return "UNKNOWN";
}
}
}
public static String expandFilepath(final String path) {
ParamUtil.requireNonBlank("path", path);
return path.startsWith("~" + File.separator)
? System.getProperty("user.home") + path.substring(1) : path;
}
public static File expandFilepath(final File file) {
String path = file.getPath();
String expandedPath = expandFilepath(path);
if (path.equals(expandedPath)) {
return file;
} else {
return new File(expandedPath);
}
}
public static String convertSequenceName(final String sequenceName) {
StringBuilder sb = new StringBuilder();
int len = sequenceName.length();
for (int i = 0; i < len; i++) {
char ch = sequenceName.charAt(i);
if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
sb.append(ch);
} else {
sb.append("_");
}
}
return sb.toString();
}
public static void writeShort(short value, byte[] dest, int destOffset) {
dest[destOffset] = (byte) (value >> 8);
dest[destOffset + 1] = (byte) (0xFF & value);
}
public static short parseShort(byte[] bytes, int offset) {
return (short) ((toInt(bytes[offset]) << 8)
| toInt(bytes[offset + 1]));
}
public static void writeInt(int value, byte[] dest, int destOffset) {
dest[destOffset] = (byte) (value >> 24);
dest[destOffset + 1] = (byte) (0xFF & (value >> 16));
dest[destOffset + 2] = (byte) (0xFF & (value >> 8));
dest[destOffset + 3] = (byte) (0xFF & value);
}
public static int parseInt(byte[] bytes, int offset) {
return toInt(bytes[offset]) << 24
| toInt(bytes[offset + 1]) << 16
| toInt(bytes[offset + 2]) << 8
| toInt(bytes[offset + 3]);
}
private static int toInt(byte bb) {
return (bb < 0) ? 256 + bb : bb;
}
public static String base64Encode(final byte[] data, final boolean withLineBreak) {
String b64Str = Base64.getEncoder().encodeToString(data);
if (!withLineBreak) {
return b64Str;
}
if (b64Str.length() < 64) {
return b64Str;
}
StringBuilder sb = new StringBuilder();
final int blockSize = 64;
final int size = b64Str.length();
final int nFullBlock = size / blockSize;
for (int i = 0; i < nFullBlock; i++) {
int offset = i * blockSize;
sb.append(b64Str.subSequence(offset, offset + blockSize)).append("\n");
}
if (size % blockSize != 0) {
sb.append(b64Str.substring(nFullBlock * blockSize)).append("\n");
}
sb.deleteCharAt(sb.length() - 1);
return sb.toString();
}
public static HttpURLConnection openHttpConn(final URL url) throws IOException {
ParamUtil.requireNonNull("url", url);
URLConnection conn = url.openConnection();
if (conn instanceof HttpURLConnection) {
return (HttpURLConnection) conn;
}
throw new IOException(url.toString() + " is not of protocol HTTP: " + url.getProtocol());
}
}