Commit c6f99429 by Jessica Hawkwell

Now self-installing.

1 parent efd6daef
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>me.felinewith</groupId>
<groupId>me.felinewith.lang_toolkit.apps</groupId>
<artifactId>bootstrap</artifactId>
<packaging>pom</packaging>
<packaging>jar</packaging>
<name>Bootstrap</name>
<version>1.0-SNAPSHOT</version>
<inceptionYear>2017</inceptionYear>
......@@ -16,6 +16,37 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/ma
<relativePath>../..</relativePath>
</parent>
<!-- url>${gl.pages}</url -->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>../..</directory>
<targetPath>DEPS</targetPath>
<includes>
<include>pom.xml</include>
</includes>
</resource>
</resources>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
<classpathLayoutType>repository</classpathLayoutType>
<mainClass>me.felinewith.lang_toolkit.apps.bootstrap.Bootstrap</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
package me.felinewith.lang_toolkit.apps.bootstrap;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import me.felinewith.lang_toolkit.apps.bootstrap.util.MavenArtifact;
/**
*
* @author jlhawkwell
*/
public class Bootstrap {
private static String PROPERTIES = "META-INF/maven/me.felinewith.lang_toolkit.apps/bootstrap/pom.properties";
public static void main(String[] args) throws IOException {
boolean mvn = false;
try { mvn = check_maven(); }
catch (IOException | InterruptedException ex) { }
if ( !mvn ) {
System.err.println("Cannot continue - maven not installed.");
Runtime.getRuntime().exit(-1);
}
File mavenFile;
if ( System.getProperty("os.name").equals("Windows") ) { mavenFile = new File("./maven/bin/mvn.cmd"); }
else { mavenFile = new File("./maven/bin/mvn"); }
mvn = mavenFile.exists();
StringBuilder sb = new StringBuilder(System.getProperty("user.home"));
sb.append("/.local/share/lang-toolkit/");
File folder = new File(sb.toString());
if ( !folder.exists() ) { folder.mkdirs(); }
boolean installed = false;
try { installed = checkProperties(sb.toString()); }
catch (IOException ex) { }
if ( !installed ) {
File test = new File(sb.toString().concat("pom.xml"));
String pt = "DEPS/pom.xml";
try { copyContents(Bootstrap.class.getClassLoader().getResourceAsStream(pt), new FileOutputStream(test)); }
catch (FileNotFoundException ex) { Logger.getLogger(Bootstrap.class.getName()).log(Level.SEVERE, null, ex); }
String[] deps = getDepList(test);
StringBuilder command = new StringBuilder();
if ( mvn ) { command.append(mavenFile.getAbsolutePath()); }
else { command.append("mvn"); }
command.append(" -N ");
try { exec(folder, command.toString().concat("-DincludeScope=runtime dependency:resolve")); }
catch (InterruptedException ex) { }
command.append("dependency:get -Dartifact=");
for ( String s : deps )
{
try { exec(folder, command.toString().concat(s)); }
catch (InterruptedException ex) { }
}
test = new File(sb.toString().concat("pom.properties"));
try { copyContents(Bootstrap.class.getClassLoader().getResourceAsStream(PROPERTIES), new FileOutputStream(test)); }
catch(FileNotFoundException ex) {}
}
}
private static boolean check_maven() throws IOException, InterruptedException {
File mvn_folder = new File("./maven/");
File test;
if ( mvn_folder.exists() ) {
test = new File("./maven/bin/mvn");
return test.exists();
}
else {
File mvn_archive = new File("maven.zip");
if ( mvn_archive.exists() ) {
File f;
String pt;
ZipInputStream zis = new ZipInputStream(new FileInputStream(mvn_archive));
ZipEntry ze = zis.getNextEntry();
while ( ze != null )
{
pt = ze.getName().replaceFirst("[^/]+", "");
f = new File(mvn_folder.getCanonicalPath().concat(pt));
System.out.println(pt);
if ( ze.isDirectory() ) {
f.mkdirs();
}
else {
f.createNewFile();
copyContents(zis, new FileOutputStream(f));
zis.closeEntry();
if ( pt.startsWith("/bin/") ) { f.setExecutable(true, false); }
f.setLastModified(ze.getLastModifiedTime().toMillis());
f.setReadable(true, false);
f.setWritable(false, false);
}
ze = zis.getNextEntry();
}
return true;
}
Process maven;
maven = Runtime.getRuntime().exec("mvn -v");
maven.waitFor();
if ( maven.exitValue() == 0 ) { return true; }
}
return false;
}
private static void copyContents(InputStream input, OutputStream output) throws IOException {
int i = 0;
byte[] data = new byte[4096];
int offset = 0;
int length = 4096;
while ( (i = input.read(data, offset, length)) > 0 ) {
output.write(data, offset, i);
}
output.close();
}
private static boolean checkProperties(String folder) throws FileNotFoundException, IOException {
Properties pomProps = new Properties();
pomProps.load(Bootstrap.class.getClassLoader().getResourceAsStream(PROPERTIES));
Properties pomTest = new Properties();
File test = new File(folder.concat("pom.properties"));
if ( test.exists() ) { pomTest.load(new FileInputStream(test)); }
else { return false; }
return compareProperties(pomProps, pomTest);
}
/**
* Compares two sets of Properties for equivalents
* @param source Base property list
* @param target Check property list
* @return true if equivalent, false if not
*/
private static boolean compareProperties(Properties source, Properties target) {
Iterator<String> names = source.stringPropertyNames().iterator();
String pName;
while ( names.hasNext() ) {
pName = names.next();
if ( target.getProperty(pName) == null ) { return false; }
else if ( !source.getProperty(pName).equals(target.getProperty(pName)) ) { return false; }
}
names = target.stringPropertyNames().iterator();
while ( names.hasNext() ) {
pName = names.next();
if ( source.getProperty(pName) == null ) { return false; }
else if ( !target.getProperty(pName).equals(source.getProperty(pName)) ) { return false; }
}
return true;
}
private static String[] getDepList(File pomFile) throws FileNotFoundException, IOException {
ArrayList<String> builder = new ArrayList<>();
FileReader fr = new FileReader(pomFile);
BufferedReader br = new BufferedReader(fr);
String line = br.readLine();
String pt;
boolean inDep = false;
MavenArtifact ma = new MavenArtifact();
while ( line != null )
{
pt = line.trim();
if ( inDep ) {
if ( pt.startsWith("<groupId>") ) { ma.setGroup(lineFix(pt)); }
else if ( pt.startsWith("<artifactId>") ) { ma.setArtifact(lineFix(pt)); }
else if ( pt.startsWith("<version>") ) { ma.setVersion(lineFix(pt)); }
else if ( pt.startsWith("</dependency>") ) {
if ( ma.isReady() ) { builder.add(ma.getLocation()); }
inDep = false;
}
}
else {
if ( pt.startsWith("<dependency>") ) {
inDep = true;
ma = new MavenArtifact();
}
}
line = br.readLine();
}
return builder.toArray(new String[builder.size()]);
}
private static String lineFix(String input) {
String pt = input.replaceAll("<[^>]+>", "");
return pt.trim();
}
private static void exec(File pwd, String command) throws IOException, InterruptedException {
System.out.print("[shell]\t");
System.out.println(command);
ProcessBuilder pb = new ProcessBuilder();
//pb.inheritIO();
pb.directory(pwd);
pb.command(command.split(" "));
Process p = pb.start();
p.waitFor();
}
}
package me.felinewith.lang_toolkit.apps.bootstrap;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
/**
*
* @author jlhawkwel
*/
public class BootstrapClassLoader extends ClassLoader
{
/**
* HashMap for jars.
*/
private static HashMap<String, File> jars;
/**
* Set buffer length to 4096.
*/
public static final int BUFFER_LEN = 4096;
/**
* Parent class loader.
*/
private final ClassLoader parent;
/**
* Constructor.
* @param cl ClassLoader to be considered the parent
*/
public BootstrapClassLoader(ClassLoader cl)
{
parent = cl;
}
/** Initialize this ClassLoader.
*/
public void init()
{
jars = new HashMap<>();
StringBuilder sb = new StringBuilder(System.getProperty("user.dir"));
sb.append(File.separator);
sb.append(System.getProperty("java.class.path"));
String st;
addJar(new File(sb.toString()));
Manifest mf = new Manifest();
try
{
JarFile jf = new JarFile(sb.toString());
ZipEntry ze = jf.getEntry("META-INF/MANIFEST.MF");
mf.read(jf.getInputStream(ze));
}
catch ( IOException x ) { System.out.println("Whoops!"); return; }
if ( mf.getMainAttributes().isEmpty() ) { System.out.println("No manifest?"); return; }
st = mf.getMainAttributes().getValue("Class-Path");
String[] pt = st.split(" ");
sb = new StringBuilder(System.getProperty("user.home"));
sb.append("/.m2/repository/");
File f;
for ( String s : pt )
{
f = new File(sb.toString().concat(s));
if ( f.exists() ) { addJar(f); }
}
}
@Override public URL getResource(final String path)
{ return getResource(true, path); }
private URL getResource(boolean goup, final String path)
{
String pth;
URL u = null;
if ( path.startsWith("/") ) { pth = path.substring(1); }
else { pth = path; }
try { u = this.getResourceLocator(pth); }
catch ( Throwable t ) { }
if ( (u == null) && goup ) { u = parent.getResource(path); }
return u;
}
private URL getResourceLocator(final String path) throws Throwable
{
JarFile jf;
ZipEntry ze;
if ( !jars.isEmpty() )
{
for ( File f : jars.values().toArray(new File[jars.size()]) )
{
jf = new JarFile(f);
ze = jf.getJarEntry(path);
if ( ze != null )
{
URL u = new URL("jar:file:".concat(f.getCanonicalPath()).concat("!/").concat(path));
return u;
}
}
}
return null;
}
@Override public InputStream getResourceAsStream(final String path)
{ return getResourceAsStream(true, path); }
private InputStream getResourceAsStream(boolean goup, final String path)
{
final URL u = this.getResource(goup, path);
if ( u == null ) { return null; }
try { return u.openStream(); }
catch ( IOException e ) { e.printStackTrace(System.out); }
return null;
}
@Override public Class<?> loadClass(final String name) throws ClassNotFoundException
{ return this.loadClass(name, true); }
@Override protected Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException
{
Class<?> cls;
/*Class<?> cls = findLoadedClass(name);
if ( cls != null ) { return cls; } // */
final InputStream is = this.getResourceAsStream(false, name.replaceAll("\\.", "/").concat(".class"));
if ( is == null ) { cls = parent.loadClass(name); }
else
{
try { return loadClassWorker(name, resolve, is); }
catch ( IOException ex ) { throw new ClassNotFoundException("Couln't load ".concat(name)); }
}
return cls;
}
private Class<?> loadClassWorker(final String name, final boolean resolve, final InputStream is)
throws ClassNotFoundException, IOException
{
Class<?> cls;
final byte[] buffer = new byte[BUFFER_LEN];
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] bytecode;
int i;
while ( (i = is.read(buffer, 0, BUFFER_LEN)) > 0 )
{ baos.write(buffer, 0, i); }
is.close();
bytecode = baos.toByteArray();
if ( bytecode == null ) { throw new ClassNotFoundException("Cannot load class: " + name); }
try
{
cls = this.defineClass(name, bytecode, 0, bytecode.length);
if ( resolve ) { this.resolveClass(cls); }
}
catch ( SecurityException e ) { cls = parent.loadClass(name); }
return cls;
}
public void addJar(File jar)
{
String pt = null;
try { pt = jar.getCanonicalPath(); }
catch (IOException ex) { Logger.getLogger(BootstrapClassLoader.class.getName()).log(Level.SEVERE, null, ex); }
if ( pt != null )
{
if ( !jars.containsKey(pt) )
{
jars.put(pt, new File(pt));
System.out.println("Added ".concat(pt));
}
}
}
}
package me.felinewith.lang_toolkit.apps.bootstrap.util;
/**
*
* @author jlhawkwell
*/
public class MavenArtifact {
private String g;
private String a;
private String v;
public MavenArtifact() {
g = "";
a = "";
v = "";
}
public MavenArtifact(String group) {
g = group;
a = "";
v = "";
}
public MavenArtifact(String group, String artifact) {
g = group;
a = artifact;
v = "";
}
public MavenArtifact(String group, String artifact, String version) {
g = group;
a = artifact;
v = version;
}
public void setGroup(String group) { if ( g.isEmpty() ) { g = group; } }
public void setArtifact(String artifact) { if ( a.isEmpty() ) { a = artifact; } }
public void setVersion(String version) { if ( v.isEmpty() ) { v = version; } }
public boolean isReady()
{
if ( g.isEmpty() || a.isEmpty() || v.isEmpty() ) { return false; }
else { return true; }
}
public String getGroup() { return g; }
public String getArtifact() { return a; }
public String getVersion() { return v; }
public String getLocation()
{
if ( !isReady( ) ) { return ""; }
StringBuilder sb = new StringBuilder(g);
sb.append(":");
sb.append(a);
sb.append(":");
sb.append(v);
return sb.toString();
}
}
package me.felinewtih.lang_toolkit;
import java.io.File;
/**
*
* @author jlhawkwell
*/
public class Bootstrap
{
public static void main(String[] args)
{
StringBuilder sb = new StringBuilder(System.getProperty("user.home"));
sb.append(File.separator);
sb.append(".m2");
File f = new File(sb.toString());
}
}
......@@ -78,8 +78,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/ma
<developers>
<developer>
<id>jlhawkwell@ladyserenakitty.com</id>
<id>jlhawkwell</id>
<name>Jessica Hawkwell</name>
<email>[email protected]</email>
<organization>StarPhoenix Media</organization>
<organizationUrl>http://starphoenixmedia.com/</organizationUrl>
<timezone>-5</timezone>
......@@ -122,6 +123,30 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/ma
</repository>
</repositories>
<dependencyManagement>
<dependencies>
<!-- PROJECT DEPENDENCIES ********************************************************************* PROJECT DEPENDENCIES -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
<scope>runtime</scope>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.8.7</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>me.felinewith.lang_toolkit.apps</groupId>
<artifactId>bootstrap</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.testng</groupId>
......@@ -297,25 +322,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/ma
</plugins>
</reporting>
<dependencyManagement>
<dependencies>
<!-- PROJECT DEPENDENCIES ********************************************************************* PROJECT DEPENDENCIES -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
<scope>runtime</scope>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.8.7</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
<profiles>
<profile>
<id>ci</id>
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!