package org.eclipse.osgi.storage;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.concurrent.TimeUnit;
import org.eclipse.osgi.internal.debug.Debug;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
public class StorageUtil {
public static final byte NULL = 0;
public static final byte OBJECT = 1;
public static void copyDir(File inDir, File outDir) throws IOException {
String[] files = inDir.list();
if (files != null && files.length > 0) {
outDir.mkdir();
for (String file : files) {
File inFile = new File(inDir, file);
File outFile = new File(outDir, file);
if (inFile.isDirectory()) {
copyDir(inFile, outFile);
} else {
InputStream in = new FileInputStream(inFile);
readFile(in, outFile);
}
}
}
}
public static void readFile(InputStream in, File file) throws IOException {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
byte buffer[] = new byte[1024];
int count;
while ((count = in.read(buffer, 0, buffer.length)) > 0) {
fos.write(buffer, 0, count);
}
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ee) {
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException ee) {
}
}
}
}
public static boolean rm(File file, boolean DEBUG) {
if (file.exists()) {
if (file.isDirectory()) {
String list[] = file.list();
if (list != null) {
int len = list.length;
for (int i = 0; i < len; i++) {
rm(new File(file, list[i]), DEBUG);
}
}
}
if (DEBUG) {
if (file.isDirectory()) {
Debug.println("rmdir " + file.getPath());
} else {
Debug.println("rm " + file.getPath());
}
}
boolean success = file.delete();
if (DEBUG) {
if (!success) {
Debug.println(" rm failed!");
}
}
return (success);
}
return (true);
}
public static String readString(DataInputStream in, boolean intern) throws IOException {
byte type = in.readByte();
if (type == NULL)
return null;
return intern ? in.readUTF().intern() : in.readUTF();
}
public static void writeStringOrNull(DataOutputStream out, String string) throws IOException {
if (string == null)
out.writeByte(NULL);
else {
out.writeByte(OBJECT);
out.writeUTF(string);
}
}
public static ServiceRegistration<?> register(String name, Object service, BundleContext context) {
Dictionary<String, Object> properties = new Hashtable<>();
properties.put(Constants.SERVICE_RANKING, Integer.valueOf(Integer.MAX_VALUE));
properties.put(Constants.SERVICE_PID, context.getBundle().getBundleId() + "." + service.getClass().getName());
return context.registerService(name, service, properties);
}
public static boolean canWrite(File installDir) {
if (installDir.canWrite() == false)
return false;
if (!installDir.isDirectory())
return false;
File fileTest = null;
try {
fileTest = File.createTempFile("writableArea", ".dll", installDir);
} catch (IOException e) {
return false;
} finally {
if (fileTest != null)
fileTest.delete();
}
return true;
}
public static URL encodeFileURL(File file) throws MalformedURLException {
return file.toURI().toURL();
}
public static byte[] getBytes(InputStream in, int length, int BUF_SIZE) throws IOException {
byte[] classbytes;
int bytesread = 0;
int readcount;
try {
if (length > 0) {
classbytes = new byte[length];
for (; bytesread < length; bytesread += readcount) {
readcount = in.read(classbytes, bytesread, length - bytesread);
if (readcount <= 0)
break;
}
} else {
length = BUF_SIZE;
classbytes = new byte[length];
readloop: while (true) {
for (; bytesread < length; bytesread += readcount) {
readcount = in.read(classbytes, bytesread, length - bytesread);
if (readcount <= 0)
break readloop;
}
byte[] oldbytes = classbytes;
length += BUF_SIZE;
classbytes = new byte[length];
System.arraycopy(oldbytes, 0, classbytes, 0, bytesread);
}
}
if (classbytes.length > bytesread) {
byte[] oldbytes = classbytes;
classbytes = new byte[bytesread];
System.arraycopy(oldbytes, 0, classbytes, 0, bytesread);
}
} finally {
try {
in.close();
} catch (IOException ee) {
}
}
return classbytes;
}
public static boolean move(File from, File to, boolean DEBUG) {
final int maxTries = 10;
final int sleepStep = 200;
for (int tryCount = 0, sleep = sleepStep;; sleep += sleepStep, tryCount++) {
if (from.renameTo(to)) {
return true;
}
if (DEBUG) {
Debug.println("move: failed to rename " + from + " to " + to + " (" + (maxTries - tryCount) + " attempts remaining)");
}
if (tryCount >= maxTries) {
break;
}
try {
TimeUnit.MILLISECONDS.sleep(sleep);
} catch (InterruptedException e) {
}
}
try {
if (from.isDirectory()) {
copyDir(from, to);
} else {
readFile(new FileInputStream(from), to);
}
if (!rm(from, DEBUG)) {
Debug.println("move: failed to delete " + from + " after copy to " + to + ". Scheduling for delete on JVM exit.");
from.deleteOnExit();
}
return true;
} catch (IOException e) {
if (DEBUG) {
Debug.println("move: failed to copy " + from + " to " + to);
Debug.printStackTrace(e);
}
return false;
}
}
}