Skip to content
Permalink
Browse files

Begin work on a built-in webserver

  • Loading branch information
LadyCailin committed Nov 20, 2019
1 parent e614b25 commit aa617823f0fb9ed24af44429607778e6c3630031
@@ -37,5 +37,6 @@
<org-netbeans-modules-editor-indent.text.plain.CodeStyle.project.wrapArrayInit>WRAP_ALWAYS</org-netbeans-modules-editor-indent.text.plain.CodeStyle.project.wrapArrayInit>
<org-netbeans-modules-editor-indent.text.plain.CodeStyle.project.wrapArrayInitItems>WRAP_ALWAYS</org-netbeans-modules-editor-indent.text.plain.CodeStyle.project.wrapArrayInitItems>
<org-netbeans-modules-editor-indent.text.plain.CodeStyle.project.wrapObjects>WRAP_ALWAYS</org-netbeans-modules-editor-indent.text.plain.CodeStyle.project.wrapObjects>
<netbeans.hint.jdkPlatform>AdoptOpenJDK_1.8</netbeans.hint.jdkPlatform>
</properties>
</project-shared-configuration>
@@ -10,6 +10,9 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.io.FileUtils;
@@ -58,11 +61,33 @@ private static synchronized void freeLock(File file) throws IOException {

public static String read(File f) throws IOException {
return org.apache.commons.io.FileUtils.readFileToString(f, "UTF-8");
// try {
// return read(f, "UTF-8");
// } catch (UnsupportedEncodingException ex) {
// throw new Error(ex);
// }
}

/**
* Fully reads data from the given file channel, and returns a byte array. If the file is too large to fit
* in memory, an IOException is thrown.
* @param channel
* @return
* @throws IOException
*/
public static byte[] readData(FileChannel channel) throws IOException {
if(channel.size() > Integer.MAX_VALUE) {
throw new IOException("File too large to read into memory. Use a stream reader.");
}
ByteBuffer buffer = ByteBuffer.allocate((int) channel.size());
channel.read(buffer);
return buffer.array();
}

/**
* Fully reads data from the given file channel, and returns it as a UTF-8 string. If the file is too large to
* fit in memory, an IOException is thrown.
* @param channel
* @return
* @throws IOException
*/
public static String read(FileChannel channel) throws IOException {
return new String(readData(channel), "UTF-8");
}

public static String read(File file, String charset) throws IOException {
@@ -205,63 +230,30 @@ public static void write(byte[] data, File file, int mode, boolean create) throw
file.getAbsoluteFile().createNewFile();
}
FileUtils.writeByteArrayToFile(file, data, append);
// try {
// synchronized (getLock(file)) {
// int sleepTime = 0;
// int sleepTimes = 0;
// loop: while(true){
// try {
// Thread.sleep(sleepTime);
// sleepTime += 10;
// sleepTimes++;
// } catch (InterruptedException ex) {
// //
// }
// RandomAccessFile raf = new RandomAccessFile(file, "rw");
// FileLock lock = null;
// try {
// lock = raf.getChannel().lock();
// //Clear out the file
// if(!append) {
// raf.getChannel().truncate(0);
// } else {
// raf.seek(raf.length());
// }
// //Write out the data
// MappedByteBuffer buf = raf.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, data.length);
// buf.put(data);
// buf.force();
// //We assume it worked at this point, so let's break;
// break loop;
// //raf.getChannel().write(ByteBuffer.wrap(data));
// } catch (IOException e){
// //If we get this dumb message, we're on windows. We'll try again here shortly,
// //but we don't want to bother the user with this exception if we can help it.
// //http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6354433
// if(!"The requested operation cannot be performed on a file with a user-mapped section open"
// .equals(e.getMessage())){
// throw e;
// }
// if(sleepTimes > 10){
// //Eh. Gotta give up some time.
// throw e;
// }
// } finally {
// if(lock != null) {
// lock.release();
// }
// raf.close();
// raf = null;
// System.gc();
// }
// }
// }
// } finally {
// freeLock(file);
// }
// FileWriter fw = new FileWriter(f, append);
// fw.write(s);
// fw.close();
}

/**
* Writes the given string to the existing file channel. UTF-8 encoding is assumed.
* @param fileChannel
* @param data
* @throws IOException
*/
public static void write(FileChannel fileChannel, String data) throws IOException {
try {
write(fileChannel, data.getBytes("UTF-8"));
} catch(UnsupportedEncodingException ex) {
throw new Error(ex);
}
}

/**
* Writes the given data to the existing file channel.
* @param fileChannel
* @param data
* @throws IOException
*/
public static void write(FileChannel fileChannel, byte[] data) throws IOException {
fileChannel.write(ByteBuffer.wrap(data));
}

/**
@@ -1,5 +1,14 @@
package com.laytonsmith.PureUtilities.Common;

import com.laytonsmith.PureUtilities.CommandExecutor;
import com.laytonsmith.PureUtilities.JavaVersion;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* This class contains utilities that help with OS specific tasks.
*
@@ -97,4 +106,132 @@ public static OS GetOS() {
public static String GetLineEnding() {
return System.getProperty("line.separator");
}

/**
* Returns the process id of the currently running Java process. In Java versions &lt; 9, this actually just a best
* effort, and it is possible in some implementations of Java, this will cause an Exception. However, if Java 9 or
* greater is running, this will be an authoritative response.
* @return
* @throws UnsupportedOperationException If the java implementation does not have correct support for this
* operation.
*/
public static long GetMyPid() throws UnsupportedOperationException {
if(JavaVersion.getMajorVersion() >= 9) {
try {
// Since we compile against Java 8, we can't directly use the class, and have to use reflection.
// If Java 8 support is dropped, this can be uncommented and simplified.
// return ProcessHandle.current().pid();
Class ProcessHandle = Class.forName("java.lang.ProcessHandle");
Object current = ReflectionUtils.invokeMethod(ProcessHandle, null, "current");
Object pid = ReflectionUtils.invokeMethod(ProcessHandle, current, "pid");
return (Long) pid;
} catch(ClassNotFoundException ex) {
throw new UnsupportedOperationException(ex);
}
} else {
final String jvmName = ManagementFactory.getRuntimeMXBean().getName();
final int index = jvmName.indexOf('@');

try {
return Long.parseLong(jvmName.substring(0, index));
} catch (NumberFormatException e) {
//
}
throw new UnsupportedOperationException("Cannot find pid");
}
}

public static class ProcessInfo {
private long pid;
private String command;

ProcessInfo(long pid, String command) {
this.pid = pid;
this.command = command;
}

/**
* Returns the process id of the given process.
* @return
*/
public long getPid() {
return pid;
}

/**
* Returns the process name, i.e. "nginx" on linux or "cmd.exe" on windows.
* @return
*/
public String getCommand() {
return command;
}

@Override
public String toString() {
return pid + ": " + command;
}

}

/**
* Returns a list of processes running on this system.
* @return
*/
public static List<ProcessInfo> GetRunningProcesses() {
try {
if(GetOS().isWindows()) {
return GetRunningProcessesWindows();
} else if(GetOS().isUnixLike()) {
return GetRunningProcessesUnix();
} else {
throw new UnsupportedOperationException("Unsupported OS");
}
} catch(IOException | InterruptedException ex) {
throw new RuntimeException(ex);
}
}

private static List<ProcessInfo> GetRunningProcessesWindows() throws InterruptedException, IOException {
List<ProcessInfo> list = new ArrayList<>();
String cmd = CommandExecutor.Execute("tasklist.exe /fo list");
String imageName = null;
String pid = null;
for(String line : cmd.split("\n|\r\n|\n\r")) {
line = line.trim();
if(line.isEmpty()) {
if(imageName != null) {
list.add(new ProcessInfo(Long.parseLong(pid), imageName));
}
continue;
}
if(line.startsWith("Image Name")) {
imageName = line.replaceAll("Image Name:\\s*(.*)", "$1");
continue;
}
if(line.startsWith("PID")) {
pid = line.replaceAll("PID:\\s*(.*)", "$1");
}
}
return list;
}

private static List<ProcessInfo> GetRunningProcessesUnix() throws InterruptedException, IOException {
List<ProcessInfo> list = new ArrayList<>();
String cmd = CommandExecutor.Execute("ps -ea");
boolean first = true;
for(String line : cmd.split("\n|\r\n|\n\r")) {
if(first) {
// First line is header
first = false;
continue;
}
line = line.trim();
String[] params = line.split("\\s+", 4);
list.add(new ProcessInfo(Long.parseLong(params[0]), params[3]));
}
return list;
}



}
@@ -74,4 +74,28 @@ public static void raise(SignalType type) {
boolean handle(SignalType type);
}

/**
* In many cases, you just want to register for the signals that are meant to terminate the program, so you can
* do a graceful shutdown. In those cases, you can simply call this method, and provide the handler, and it will
* register it with the SIGINT and SIGTERM signals.
* <p>
* Unlike {@link #addHandler}, this provides no way to obtain previously registered handlers. Also unlike
* addHandler, no {@link IllegalArgumentException} will be thrown if the signals can't be bound. Thus, this is
* a best effort attempt, and if you need to positively know if a signal couldn't be bound, don't use this
* method.
* @param handler
*/
public static void addStopHandlers(SignalCallback handler) {
try {
addHandler(Signals.SIGTERM, handler);
} catch (IllegalArgumentException ex) {
//
}
try {
addHandler(Signals.SIGINT, handler);
} catch (IllegalArgumentException ex) {
//
}
}

}
@@ -1,7 +1,7 @@
package com.laytonsmith.PureUtilities;

/**
*
* The interface for various signal types. See {@link Signals} for various default implementations.
*/
public interface SignalType {

@@ -29,6 +29,10 @@ public CREUnsupportedOperationException(String msg, Target t, Throwable cause) {
super(msg, t, cause);
}

public CREUnsupportedOperationException(UnsupportedOperationException ex, Target t) {
super(ex.getMessage(), t, ex);
}

@Override
public String docs() {
return "If an operation is not supported, this exception can be thrown.";
@@ -48,6 +48,8 @@ protected AbstractFunction() {
}

/**
* {@inheritDocs}
*
* By default, we return CVoid.
*
* @param t

0 comments on commit aa61782

Please sign in to comment.
You can’t perform that action at this time.