001/*
002  GRANITE DATA SERVICES
003  Copyright (C) 2011 GRANITE DATA SERVICES S.A.S.
004
005  This file is part of Granite Data Services.
006
007  Granite Data Services is free software; you can redistribute it and/or modify
008  it under the terms of the GNU Library General Public License as published by
009  the Free Software Foundation; either version 2 of the License, or (at your
010  option) any later version.
011
012  Granite Data Services is distributed in the hope that it will be useful, but
013  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
015  for more details.
016
017  You should have received a copy of the GNU Library General Public License
018  along with this library; if not, see <http://www.gnu.org/licenses/>.
019*/
020
021package org.granite.scan;
022
023import java.io.InputStream;
024import java.util.Properties;
025
026import org.granite.logging.Logger;
027
028/**
029 * @author Franck WOLFF
030 */
031public class ScannerFactory {
032        
033        private static final Logger log = Logger.getLogger(ScannerFactory.class);
034
035        
036        public static Scanner createScanner(ScannedItemHandler handler, String marker) {
037        if (isVFSAvailable() && !isEmbedded() && isJBoss(5)) {
038                log.debug("Using VFS aware scanner");
039                try {
040                        Class<?> vfsScannerClass = ScannerFactory.class.getClassLoader().loadClass("org.granite.scan.VFSScanner");
041                        return (Scanner)vfsScannerClass.getConstructor(ScannedItemHandler.class, String.class).newInstance(handler, marker);                    
042                }
043                catch (Exception e) {
044                        throw new RuntimeException("Could not create VFSScanner", e);
045                }
046        }
047        if (isVFS3Available() && !isEmbedded() && isJBoss(6)) {
048                log.debug("Using VFS3 aware scanner");
049                try {
050                        Class<?> vfsScannerClass = ScannerFactory.class.getClassLoader().loadClass("org.granite.scan.VFS3Scanner");
051                        return (Scanner)vfsScannerClass.getConstructor(ScannedItemHandler.class, String.class).newInstance(handler, marker);                    
052                }
053                catch (Exception e) {
054                        throw new RuntimeException("Could not create VFS3Scanner", e);
055                }
056        }
057        
058        log.debug("Using default Scanner");
059        return new URLScanner(handler, marker);
060        }
061   
062        private static boolean isVFSAvailable() {
063                try {
064                        Class.forName("org.jboss.virtual.VFS");
065                        log.trace("VFS detected");
066                        return true;
067                }
068                catch (Throwable t) {
069                        return false;
070                }
071        }
072           
073        private static boolean isVFS3Available() {
074                try {
075                        Class.forName("org.jboss.vfs.VFS");
076                        log.trace("VFS3 detected");
077                        return true;
078                }
079                catch (Throwable t) {
080                        return false;
081                }
082        }
083        
084        private static boolean isJBoss(int version) {
085                try {
086                        Properties props = new Properties();
087                        InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("/org/jboss/version.properties");
088                        if (is == null)
089                                is = Thread.currentThread().getContextClassLoader().getResourceAsStream("org/jboss/version.properties");
090                        if (is != null) {
091                                // JBoss AS 4, 5, 6
092                                props.load(is);
093                                is.close();
094                                int major = Integer.parseInt(props.getProperty("version.major"));
095                                int minor = Integer.parseInt(props.getProperty("version.minor"));
096                                
097                                boolean isJBossVersion = major >= version && minor >= 0;
098                                if (isJBossVersion)
099                                        log.trace("JBoss " + major + "." + minor + " detected");
100                                
101                                return isJBossVersion;
102                        }
103                        
104                        // JBoss AS 7 ?
105                        log.trace("JBoss AS 7+ detected");
106                        
107                        return true;
108                }
109                catch (Throwable t) {
110                        return false;
111                }
112        }
113        
114        private static boolean isEmbedded() {
115                try {
116                        Class.forName("org.jboss.embedded.Bootstrap");
117                        log.trace("JBoss Embedded detected");
118                        return true;
119                }
120                catch (Throwable t) {
121                        return false;
122                }
123        }
124}