package net.sf.lab3f.util; import java.io.File; import java.io.InputStream; import java.io.IOException; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.OutputStream; import java.nio.ByteBuffer; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; import java.nio.channels.WritableByteChannel; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.net.URL; import java.net.MalformedURLException; import java.nio.channels.Channels; import java.nio.channels.WritableByteChannel; import java.security.MessageDigest; /** * Реализация интерфейсов TuttiFruttiable и Groovyable. Обратите * внимание, что вследствие слишком большого объема jar-библиотеки * Groovy включить ее в бандл не удалось, поэтому метод содержит * специфический ClassLoader. */ public class Main implements /*Groovyable,*/ TuttiFruttiable{ private Object groovyShell; private ClassLoader groovyRootLoader; public String join(String[] sa, String j){ StringBuffer sb = new StringBuffer(); for(String s : sa)sb.append(s + j); String ret = sb.toString(); return ret.substring(0, ret.lastIndexOf(j)); } public Object eval(InputStream is)throws Exception { return getGroovyEvalMethod(InputStream.class).invoke(groovyShell, new Object[]{is}); } public Object eval(File f)throws Exception { return getGroovyEvalMethod(File.class).invoke(groovyShell, new Object[]{f}); } public Object eval(String script)throws Exception { return getGroovyEvalMethod(String.class).invoke(groovyShell, new Object[]{script}); } private class GroovyLoader extends ClassLoader{ private URL jarUrl; public Class findClass(String cln){ try{ if(jarUrl == null)jarUrl = new URL("jar:file:lib/groovy.jar!/"); URL url = new URL(jarUrl, cln.replace('.', '/') + ".class"); final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final WritableByteChannel wbch = Channels.newChannel(baos); ch2ch(Channels.newChannel(url.openStream()), wbch); final byte[] ba = baos.toByteArray(); return defineClass(cln, ba, 0, ba.length); } catch(IOException ex){return null;} } protected final URL findResource(String name){ try{return new URL(jarUrl, name);} catch(MalformedURLException ex){return null;} } } public byte[] getMd5Bytes(byte[] ba){ try{ MessageDigest digest = MessageDigest.getInstance("MD5"); digest.update(ba); return digest.digest(); } catch(java.security.NoSuchAlgorithmException ex){return null;} } public String getMd5String(String s){ try{ MessageDigest digest = MessageDigest.getInstance("MD5"); digest.update(s.getBytes()); return toHexString(digest.digest()); } catch(java.security.NoSuchAlgorithmException ex){return null;} } public String toHexString(byte[] block) { StringBuffer buf = new StringBuffer(); char[] hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; int len = block.length; int high = 0; int low = 0; for (int i = 0; i < len; i++) { high = ((block[i] & 0xf0) >> 4); low = (block[i] & 0x0f); buf.append(hexChars[high]); buf.append(hexChars[low]); } return buf.toString(); } public final String stream2string(InputStream is) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); stream2stream(is, baos); byte[] ba = baos.toByteArray(); return new String(ba, "UTF8"); } public final void stream2stream(InputStream is, OutputStream os) throws IOException { ch2ch(Channels.newChannel(is), Channels.newChannel(os)); is.close(); os.close(); } public final void ch2ch(final ReadableByteChannel src, final WritableByteChannel dest) throws IOException { final ByteBuffer buffer = ByteBuffer.allocateDirect(16 * 1024); while (src.read(buffer) != -1) { buffer.flip(); dest.write(buffer); buffer.compact(); } buffer.flip(); while (buffer.hasRemaining())dest.write(buffer); } private final String Base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; public byte[] decodeB64(String str) { if (str.length() % 4 != 0) return null; ByteArrayOutputStream bs = new ByteArrayOutputStream(); DataOutputStream ds = new DataOutputStream(bs); for (int i = 0; i < (str.length() + 3) / 4; i++) { short [] s = new short[4]; short [] t = new short[3]; for (int j = 0; j < 4; j++) s[j] = (short) Base64.indexOf(str.charAt(i*4+j)); t[0] = (short) ((s[0] << 2) + (s[1] >> 4)); if (s[2] == 64) t[1] = t[2] = (short) (-1); else if (s[3] == 64) { t[1] = (short) (((s[1] << 4) + (s[2] >> 2)) & 0xFF); t[2] = (short) (-1); } else { t[1] = (short) (((s[1] << 4) + (s[2] >> 2)) & 0xFF); t[2] = (short) (((s[2] << 6) + s[3]) & 0xFF); } try {for (int j = 0; j < 3; j++) if (t[j] >= 0) ds.writeByte(t[j]);} catch (IOException e) {} } return bs.toByteArray(); } public final String encodeB64(byte [] b) { ByteArrayOutputStream os = new ByteArrayOutputStream(); for (int i = 0; i < (b.length + 2) / 3; i++) { short [] s = new short[3]; short [] t = new short[4]; for (int j = 0; j < 3; j++) { if ((i * 3 + j) < b.length) s[j] = (short) (b[i*3+j] & 0xFF); else s[j] = -1; } t[0] = (short) (s[0] >> 2); if (s[1] == -1) t[1] = (short) (((s[0] & 0x3) << 4)); else t[1] = (short) (((s[0] & 0x3) << 4) + (s[1] >> 4)); if (s[1] == -1) t[2] = t[3] = 64; else if (s[2] == -1) { t[2] = (short) (((s[1] & 0xF) << 2)); t[3] = 64; } else { t[2] = (short) (((s[1] & 0xF) << 2) + (s[2] >> 6)); t[3] = (short) (s[2] & 0x3F); } for (int j = 0; j < 4; j++) os.write(Base64.charAt(t[j])); } return new String(os.toByteArray()); } private Method getGroovyEvalMethod(Class cl) throws Exception { if(groovyShell == null){ GroovyLoader gl = new GroovyLoader(); Class lcClass = Class.forName("org.codehaus.groovy.tools.LoaderConfiguration", true, gl); Class rlClass = Class.forName("org.codehaus.groovy.tools.RootLoader", true, gl); Constructor rlConstr = rlClass.getConstructor(lcClass); Object lcObj = lcClass.newInstance(); Method addCp = lcClass.getMethod("addClassPath", String.class); addCp.invoke(lcObj, new Object[]{"../_classes/raw"}); ClassLoader groovyRootLoader = (ClassLoader)rlConstr.newInstance(lcObj); Class shClass = Class.forName("groovy.lang.GroovyShell", true, groovyRootLoader); groovyShell = shClass.newInstance(); } return groovyShell.getClass().getMethod("evaluate", cl); } }