package org.mobicents.servlet.sip.annotations; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Enumeration; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.apache.log4j.Logger; /** * Utils for parwing SipApplication annotation without a classloader * * @author Vladimir Ralev * */ public class SipApplicationAnnotationUtils { private static transient Logger logger = Logger.getLogger(SipApplicationAnnotationUtils.class); private final static byte[] SIP_APPLICATION_BYTES = "SipApplication".getBytes(); private final static byte[] ANNOTATION_BYTES = "annotation".getBytes(); private static boolean contains(byte[] text, byte[] subtext) { if(text.length<subtext.length) return false; for(int q=0; q<text.length-subtext.length; q++) { boolean found = true; for(int w=0; w<subtext.length; w++) { if(text[q+w] != subtext[w]) { found = false; break; } } if(found) return true; } return false; } public static boolean findPackageInfoInArchive(File archive) { ZipFile zipFile = null; try { zipFile = new ZipFile(archive); } catch (Exception e1) { logger.error("Unable to open " + archive.getAbsolutePath() + ". No sip applications were parsed."); return false; } Enumeration<ZipEntry> entries = (Enumeration<ZipEntry>) zipFile.entries();; while (entries.hasMoreElements()) { ZipEntry entry = entries.nextElement(); if(entry.getName().contains("package-info.class")) { try { if(findSipApplicationAnnotation(zipFile.getInputStream(entry))) { return true; } } catch (IOException e) { } } } return false; } /** * Determine if there is a sip application in this folder. * * TODO: HACK: FIXME: This method reads raw class file trying to determine if it * uses the SIpApplication annotation. This seems to be reliable and a lot faster * than using a classloader, but can be reviewed in the future especially when * JBoss AS 5.0 is available with the new deployer. */ public static boolean findPackageInfoinDirectory(File file) { if(file.getName().equals("package-info.class")) { FileInputStream stream = null; try { stream = new FileInputStream (file); if(findSipApplicationAnnotation(stream)) return true; } catch (Exception e) {} finally { try { stream.close(); } catch (IOException e) { } } } if(file.isDirectory()) { for(File subFile:file.listFiles()) { if(findPackageInfoinDirectory(subFile)) return true; } } return false; } /** * Determine if this stream contains SipApplication annotations * * TODO: HACK: FIXME: This method reads raw class file trying to determine if it * uses the SIpApplication annotation. This seems to be reliable and a lot faster * than using a classloader, but can be reviewed in the future especially when * JBoss AS 5.0 is available with the new deployer. */ public static boolean findSipApplicationAnnotation(InputStream stream) { try { byte[] rawClassBytes; rawClassBytes = new byte[stream.available()]; stream.read(rawClassBytes); boolean one = contains(rawClassBytes, SIP_APPLICATION_BYTES); boolean two = contains(rawClassBytes, ANNOTATION_BYTES); if(one && two) return true; } catch (Exception e) {} return false; } }