package br.com.caelum.calopsita.infra.vraptor; import java.io.BufferedInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.lang.annotation.Annotation; import java.util.Enumeration; import java.util.jar.Attributes; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.Manifest; import javax.persistence.Entity; import javax.servlet.ServletContext; import br.com.caelum.vraptor.ComponentRegistry; import br.com.caelum.vraptor.ioc.Stereotype; public class CalopsitaPluginParser implements JarParser { private final ComponentRegistry registry; private final ServletContext context; public CalopsitaPluginParser(ComponentRegistry registry, ServletContext context) { this.registry = registry; this.context = context; } public void parse(File file) { JarFile jar = newJarFile(file); Attributes attributes = getManifest(jar).getAttributes("br.com.caelum.calopsita"); if(attributes==null) { return; } Enumeration<JarEntry> entries = jar.entries(); while (entries.hasMoreElements()) { JarEntry jarEntry = entries.nextElement(); if (jarEntry.getName().endsWith(".class")) { registerClass(jarEntry); } else if (jarEntry.getName().endsWith("messages.properties")) { appendMessages(getInputStream(jar, jarEntry)); } } } private InputStream getInputStream(JarFile jar, JarEntry jarEntry) { try { return jar.getInputStream(jarEntry); } catch (IOException e) { throw new IllegalStateException(e); } } private void appendMessages(InputStream input) { String messages = context.getRealPath("/messages.properties"); try { FileOutputStream writer = new FileOutputStream(new File(messages), true); move(input, writer); writer.close(); } catch (IOException e) { throw new IllegalStateException(e); } } private void move(InputStream input, FileOutputStream writer) throws IOException { BufferedInputStream bis = new BufferedInputStream(input); byte[] content = new byte[1024*10]; int len; while((len = bis.read(content))!=-1) { writer.write(content, 0, len); } } private void registerClass(JarEntry jarEntry) { String className = jarEntry.getName().replaceFirst("\\.class$", "").replace('/', '.'); try { Class<?> clazz = Class.forName(className); if (isAnnotatedWithVRaptorStereotype(clazz)) { registry.register(clazz, clazz); } if (clazz.isAnnotationPresent(Entity.class)) { AnnotationConfigurationFactory.addEntity(clazz); } } catch (ClassNotFoundException e) { throw new IllegalArgumentException(e); } } private boolean isAnnotatedWithVRaptorStereotype(Class<?> clazz) { for (Annotation annotation : clazz.getAnnotations()) { if(annotation.annotationType().isAnnotationPresent(Stereotype.class)) { return true; } } return false; } private Manifest getManifest(JarFile jar){ try { Manifest manifest = jar.getManifest(); return manifest == null? new Manifest() : manifest; } catch (IOException e) { return new Manifest(); } } private JarFile newJarFile(File file) { try { return new JarFile(file); } catch (IOException e) { throw new IllegalArgumentException("It is not a valid jar file", e); } } }