001    package railo.commons.io;
002    
003    import java.io.File;
004    import java.io.IOException;
005    import java.io.PrintWriter;
006    import java.lang.management.ManagementFactory;
007    import java.lang.management.MemoryPoolMXBean;
008    import java.lang.management.MemoryType;
009    import java.lang.management.MemoryUsage;
010    import java.lang.reflect.Field;
011    import java.lang.reflect.Method;
012    import java.net.MalformedURLException;
013    import java.net.URL;
014    import java.net.URLClassLoader;
015    import java.util.ArrayList;
016    import java.util.Iterator;
017    import java.util.LinkedList;
018    import java.util.Map;
019    import java.util.Map.Entry;
020    
021    import javax.servlet.ServletContext;
022    
023    import railo.commons.digest.MD5;
024    import railo.commons.io.res.Resource;
025    import railo.commons.io.res.ResourceProvider;
026    import railo.commons.io.res.ResourcesImpl;
027    import railo.commons.io.res.util.ResourceUtil;
028    import railo.commons.lang.ClassUtil;
029    import railo.commons.lang.StringUtil;
030    import railo.runtime.Info;
031    import railo.runtime.config.Config;
032    import railo.runtime.exp.DatabaseException;
033    import railo.runtime.op.Caster;
034    import railo.runtime.type.Array;
035    import railo.runtime.type.Collection;
036    import railo.runtime.type.KeyImpl;
037    import railo.runtime.type.List;
038    import railo.runtime.type.Query;
039    import railo.runtime.type.QueryImpl;
040    
041    /**
042     * 
043     */
044    public final class SystemUtil {
045    
046            private static final Collection.Key MAX = KeyImpl.intern("max");
047            private static final Collection.Key INIT = KeyImpl.intern("init");
048            private static final Collection.Key USED = KeyImpl.intern("used");
049    
050            public static final int MEMORY_TYPE_ALL=0;
051            public static final int MEMORY_TYPE_HEAP=1;
052            public static final int MEMORY_TYPE_NON_HEAP=2;
053    
054            public static final int ARCH_UNKNOW=0;
055            public static final int ARCH_32=32;
056            public static final int ARCH_64=64;
057    
058            public static final char CHAR_DOLLAR=(char)36;
059            public static final char CHAR_POUND=(char)163;
060            public static final char CHAR_EURO=(char)8364;
061            
062            public static final PrintWriter PRINTWRITER_OUT = new PrintWriter(System.out);
063            public static final PrintWriter PRINTWRITER_ERR = new PrintWriter(System.err);
064        
065        
066            private static final boolean isWindows=System.getProperty("os.name").toLowerCase().startsWith("windows");
067        private static final boolean isUnix=!isWindows &&  File.separatorChar == '/';
068            
069        private static Resource tempFile;
070        private static Resource homeFile;
071        private static Resource[] classPathes;
072        private static String charset=System.getProperty("file.encoding");
073        private static String lineSeparator=System.getProperty("line.separator","\n");
074        private static MemoryPoolMXBean permGenSpaceBean;
075    
076            public static int osArch=-1;
077            public static int jreArch=-1;
078            
079            static {
080                    if(charset==null || charset.equalsIgnoreCase("MacRoman"))
081                            charset="cp1252";
082                    
083                    // Perm Gen
084                    permGenSpaceBean=getPermGenSpaceBean();
085                    // make sure the JVM does not always a new bean
086                    MemoryPoolMXBean tmp = getPermGenSpaceBean();
087                    if(tmp!=permGenSpaceBean)permGenSpaceBean=null;
088            }
089            
090            
091            
092            public static MemoryPoolMXBean getPermGenSpaceBean() {
093                    java.util.List<MemoryPoolMXBean> manager = ManagementFactory.getMemoryPoolMXBeans();
094                    MemoryPoolMXBean bean;
095                    // PERM GEN
096                    Iterator<MemoryPoolMXBean> it = manager.iterator();
097                    while(it.hasNext()){
098                            bean = it.next();
099                            if("Perm Gen".equalsIgnoreCase(bean.getName()) || "CMS Perm Gen".equalsIgnoreCase(bean.getName())) {
100                                    return bean;
101                            }
102                    }
103                    it = manager.iterator();
104                    while(it.hasNext()){
105                            bean = it.next();
106                            if(StringUtil.indexOfIgnoreCase(bean.getName(),"Perm Gen")!=-1 || StringUtil.indexOfIgnoreCase(bean.getName(),"PermGen")!=-1) {
107                                    return bean;
108                            }
109                    }
110                    // take none-heap when only one
111                    it = manager.iterator();
112                    LinkedList<MemoryPoolMXBean> beans=new LinkedList<MemoryPoolMXBean>();
113                    while(it.hasNext()){
114                            bean = it.next();
115                            if(bean.getType().equals(MemoryType.NON_HEAP)) {
116                                    beans.add(bean);
117                                    return bean;
118                            }
119                    }
120                    if(beans.size()==1) return beans.getFirst();
121                    
122                    // Class Memory/ClassBlock Memory?
123                    it = manager.iterator();
124                    while(it.hasNext()){
125                            bean = it.next();
126                            if(StringUtil.indexOfIgnoreCase(bean.getName(),"Class Memory")!=-1) {
127                                    return bean;
128                            }
129                    }
130                    
131                    
132                    return null;
133            }
134            
135        private static Boolean isFSCaseSensitive;
136    
137        /**
138         * returns if the file system case sensitive or not
139         * @return is the file system case sensitive or not
140         */
141        public static boolean isFSCaseSensitive() { 
142            if(isFSCaseSensitive==null) { 
143                    try { 
144                            _isFSCaseSensitive(File.createTempFile("abcx","txt"));
145                    } 
146                    catch (IOException e) { 
147                            File f = new File("abcx.txt").getAbsoluteFile();
148                            try {
149                                                    f.createNewFile();
150                                _isFSCaseSensitive(f);
151                                                    
152                                            } catch (IOException e1) {
153                                                    throw new RuntimeException(e1.getMessage());
154                                            }
155                    } 
156            } 
157            return isFSCaseSensitive.booleanValue(); 
158        }
159        private static void _isFSCaseSensitive(File f) { 
160            File temp=new File(f.getPath().toUpperCase()); 
161            isFSCaseSensitive=temp.exists()?Boolean.FALSE:Boolean.TRUE; 
162            f.delete(); 
163        }
164            
165        /**
166         * @return is local machine a Windows Machine
167         */
168        public static boolean isWindows() {
169            return isWindows;
170        }
171    
172        /**
173         * @return is local machine a Unix Machine
174         */
175        public static boolean isUnix() {
176            return isUnix;
177        }
178    
179        /**
180         * @return return System directory
181         */
182        public static Resource getSystemDirectory() {
183            String pathes=System.getProperty("java.library.path");
184            ResourceProvider fr = ResourcesImpl.getFileResourceProvider();
185            if(pathes!=null) {
186                String[] arr=List.toStringArrayEL(List.listToArray(pathes,File.pathSeparatorChar));
187                for(int i=0;i<arr.length;i++) {    
188                    if(arr[i].toLowerCase().indexOf("windows\\system")!=-1) {
189                        Resource file = fr.getResource(arr[i]);
190                        if(file.exists() && file.isDirectory() && file.isWriteable()) return ResourceUtil.getCanonicalResourceEL(file);
191                        
192                    }
193                }
194                for(int i=0;i<arr.length;i++) {    
195                    if(arr[i].toLowerCase().indexOf("windows")!=-1) {
196                            Resource file = fr.getResource(arr[i]);
197                        if(file.exists() && file.isDirectory() && file.isWriteable()) return ResourceUtil.getCanonicalResourceEL(file);
198                        
199                    }
200                }
201                for(int i=0;i<arr.length;i++) {    
202                    if(arr[i].toLowerCase().indexOf("winnt")!=-1) {
203                            Resource file = fr.getResource(arr[i]);
204                        if(file.exists() && file.isDirectory() && file.isWriteable()) return ResourceUtil.getCanonicalResourceEL(file);
205                        
206                    }
207                }
208                for(int i=0;i<arr.length;i++) {    
209                    if(arr[i].toLowerCase().indexOf("win")!=-1) {
210                            Resource file = fr.getResource(arr[i]);
211                        if(file.exists() && file.isDirectory() && file.isWriteable()) return ResourceUtil.getCanonicalResourceEL(file);
212                        
213                    }
214                }
215                for(int i=0;i<arr.length;i++) {
216                    Resource file = fr.getResource(arr[i]);
217                    if(file.exists() && file.isDirectory() && file.isWriteable()) return ResourceUtil.getCanonicalResourceEL(file);
218                }
219            }
220            return null;
221        }
222        
223        /**
224         * @return return running context root
225         */
226        public static Resource getRuningContextRoot() {
227            ResourceProvider frp = ResourcesImpl.getFileResourceProvider();
228            
229            try {
230                return frp.getResource(".").getCanonicalResource();
231            } catch (IOException e) {}
232            URL url=new Info().getClass().getClassLoader().getResource(".");
233            try {
234                return frp.getResource(FileUtil.URLToFile(url).getAbsolutePath());
235            } catch (MalformedURLException e) {
236                return null;
237            }
238        }
239        
240        /**
241         * returns the Temp Directory of the System
242         * @return temp directory
243         */
244        public static Resource getTempDirectory() {
245            if(tempFile!=null) return tempFile;
246            ResourceProvider fr = ResourcesImpl.getFileResourceProvider();
247            String tmpStr = System.getProperty("java.io.tmpdir");
248            if(tmpStr!=null) {
249                tempFile=fr.getResource(tmpStr);
250                if(tempFile.exists()) {
251                    tempFile=ResourceUtil.getCanonicalResourceEL(tempFile);
252                    return tempFile;
253                }
254            }
255            File tmp =null;
256            try {
257                    tmp = File.createTempFile("a","a");
258                tempFile=fr.getResource(tmp.getParent());
259                tempFile=ResourceUtil.getCanonicalResourceEL(tempFile);   
260            }
261            catch(IOException ioe) {}
262            finally {
263                    if(tmp!=null)tmp.delete();
264            }
265            return tempFile;
266        }
267        
268        /**
269         * returns the Hoome Directory of the System
270         * @return home directory
271         */
272        public static Resource getHomeDirectory() {
273            if(homeFile!=null) return homeFile;
274            
275            ResourceProvider frp = ResourcesImpl.getFileResourceProvider();
276            
277            String homeStr = System.getProperty("user.home");
278            if(homeStr!=null) {
279                homeFile=frp.getResource(homeStr);
280                homeFile=ResourceUtil.getCanonicalResourceEL(homeFile);
281            }
282            return homeFile;
283        }
284    
285        /**
286         * get class pathes from all url ClassLoaders
287         * @param ucl URL Class Loader
288         * @param pathes Hashmap with allpathes
289         */
290        private static void getClassPathesFromClassLoader(URLClassLoader ucl, ArrayList pathes) {
291            ClassLoader pcl=ucl.getParent();
292            // parent first
293            if(pcl instanceof URLClassLoader)
294                getClassPathesFromClassLoader((URLClassLoader) pcl, pathes);
295    
296            ResourceProvider frp = ResourcesImpl.getFileResourceProvider();
297            // get all pathes
298            URL[] urls=ucl.getURLs();
299            for(int i=0;i<urls.length;i++) {
300                Resource file=frp.getResource(urls[i].getPath());
301                if(file.exists())
302                    pathes.add(ResourceUtil.getCanonicalResourceEL(file));
303            }
304            
305        }
306        
307        /**
308         * @return returns a string list of all pathes
309         */
310        public static Resource[] getClassPathes() {
311            
312            if(classPathes!=null) 
313                return classPathes;
314            
315            ArrayList pathes=new ArrayList();
316            String pathSeperator=System.getProperty("path.separator");
317            if(pathSeperator==null)pathSeperator=";";
318                
319        // java.ext.dirs
320            ResourceProvider frp = ResourcesImpl.getFileResourceProvider();
321            
322            
323        // pathes from system properties
324            String strPathes=System.getProperty("java.class.path");
325            if(strPathes!=null) {
326                Array arr=List.listToArrayRemoveEmpty(strPathes,pathSeperator);
327                int len=arr.size();
328                for(int i=1;i<=len;i++) {
329                    Resource file=frp.getResource(Caster.toString(arr.get(i,""),"").trim());
330                    if(file.exists())
331                        pathes.add(ResourceUtil.getCanonicalResourceEL(file));
332                }
333            }
334            
335            
336        // pathes from url class Loader (dynamic loaded classes)
337            ClassLoader cl = new Info().getClass().getClassLoader();
338            if(cl instanceof URLClassLoader) 
339                getClassPathesFromClassLoader((URLClassLoader) cl, pathes);
340            
341            return classPathes=(Resource[]) pathes.toArray(new Resource[pathes.size()]);
342            
343        }
344    
345        public static long getUsedMemory() {
346            Runtime r = Runtime.getRuntime();
347            return r.totalMemory()-r.freeMemory();
348        }
349        public static long getAvailableMemory() {
350            Runtime r = Runtime.getRuntime();
351            return r.freeMemory();
352        }
353    
354        /**
355         * replace path placeholder with the real path, placeholders are [{temp-directory},{system-directory},{home-directory}]
356         * @param path
357         * @return updated path
358         */
359        public static String parsePlaceHolder(String path) {
360            if(path==null) return path;
361            // Temp
362            if(path.startsWith("{temp")) {
363                if(path.startsWith("}",5)) path=getTempDirectory().getRealResource(path.substring(6)).toString();
364                else if(path.startsWith("-dir}",5)) path=getTempDirectory().getRealResource(path.substring(10)).toString();
365                else if(path.startsWith("-directory}",5)) path=getTempDirectory().getRealResource(path.substring(16)).toString();
366            }
367            // System
368            else if(path.startsWith("{system")) {
369                if(path.startsWith("}",7)) path=getSystemDirectory().getRealResource(path.substring(8)).toString();
370                else if(path.startsWith("-dir}",7)) path=getSystemDirectory().getRealResource(path.substring(12)).toString();
371                else if(path.startsWith("-directory}",7)) path=getSystemDirectory().getRealResource(path.substring(18)).toString();
372            }
373            // Home
374            else if(path.startsWith("{home")) {
375                if(path.startsWith("}",5)) path=getHomeDirectory().getRealResource(path.substring(6)).toString();
376                else if(path.startsWith("-dir}",5)) path=getHomeDirectory().getRealResource(path.substring(10)).toString();
377                else if(path.startsWith("-directory}",5)) path=getHomeDirectory().getRealResource(path.substring(16)).toString();
378            }
379            return path;
380        }
381        
382        public static String addPlaceHolder(Resource file, String defaultValue) {
383         // Temp
384            String path=addPlaceHolder(getTempDirectory(),file,"{temp-directory}");
385            if(!StringUtil.isEmpty(path)) return path;
386         // System
387            path=addPlaceHolder(getSystemDirectory(),file,"{system-directory}");
388            if(!StringUtil.isEmpty(path)) return path;
389         // Home
390            path=addPlaceHolder(getHomeDirectory(),file,"{home-directory}");
391            if(!StringUtil.isEmpty(path)) return path;
392            
393          
394            return defaultValue;
395        }
396        
397        private static String addPlaceHolder(Resource dir, Resource file,String placeholder) {
398            if(ResourceUtil.isChildOf(file, dir)){
399                    try {
400                                    return StringUtil.replace(file.getCanonicalPath(), dir.getCanonicalPath(), placeholder, true);
401                            } 
402                    catch (IOException e) {}
403            }
404            return null;
405            }
406        
407    
408            public static String addPlaceHolder(Resource file,  Config config, String defaultValue) {
409            ResourceProvider frp = ResourcesImpl.getFileResourceProvider();
410            
411            // temp
412                    Resource dir = config.getTempDirectory();
413                    String path = addPlaceHolder(dir,file,"{temp-directory}");
414                    if(!StringUtil.isEmpty(path)) return path;
415                    
416            // Config 
417                    dir = config.getConfigDir();
418                    path = addPlaceHolder(dir,file,"{railo-config-directory}");
419                    if(!StringUtil.isEmpty(path)) return path;
420    
421            /* / Config WEB
422                    dir = config.getConfigDir();
423                    path = addPlaceHolder(dir,file,"{railo-server-directory}");
424                    if(!StringUtil.isEmpty(path)) return path;
425    */
426            // Web root
427                    dir = config.getRootDirectory();
428                    path = addPlaceHolder(dir,file,"{web-root-directory}");
429                    if(!StringUtil.isEmpty(path)) return path;
430    
431                    
432            
433                    /* TODO
434            else if(str.startsWith("{railo-server")) {
435                cs=((ConfigImpl)config).getConfigServerImpl();
436                //if(config instanceof ConfigServer && cs==null) cs=(ConfigServer) cw;
437                if(cs!=null) {
438                    if(str.startsWith("}",13)) str=cs.getConfigDir().getReal(str.substring(14));
439                    else if(str.startsWith("-dir}",13)) str=cs.getConfigDir().getReal(str.substring(18));
440                    else if(str.startsWith("-directory}",13)) str=cs.getConfigDir().getReal(str.substring(24));
441                }
442            }*/
443            
444            
445            return addPlaceHolder(file, defaultValue);
446        }
447            
448            public static String parsePlaceHolder(String path, ServletContext sc, Map<String,String> labels) {
449                    if(path==null) return null;
450            if(path.indexOf('{')!=-1){
451                    if((path.indexOf("{web-context-label}"))!=-1){
452                            String id=hash(sc);
453                            
454                            String label=labels.get(id);
455                            if(StringUtil.isEmpty(label)) label=id;
456                            
457                            path=StringUtil.replace(path, "{web-context-label}", label, false);
458                    }
459            }
460            return parsePlaceHolder(path, sc);
461        }
462        
463            public static String parsePlaceHolder(String path, ServletContext sc) {
464            ResourceProvider frp = ResourcesImpl.getFileResourceProvider();
465            
466            
467            if(path==null) return null;
468            if(path.indexOf('{')!=-1){
469                    if(StringUtil.startsWith(path,'{')){
470                        
471                        // Web Root
472                        if(path.startsWith("{web-root")) {
473                            if(path.startsWith("}",9))                                      path=frp.getResource(sc.getRealPath("/")).getRealResource(path.substring(10)).toString();
474                            else if(path.startsWith("-dir}",9))             path=frp.getResource(sc.getRealPath("/")).getRealResource(path.substring(14)).toString();
475                            else if(path.startsWith("-directory}",9))       path=frp.getResource(sc.getRealPath("/")).getRealResource(path.substring(20)).toString();
476            
477                        }
478                        else path=SystemUtil.parsePlaceHolder(path);
479                    }
480                    
481                    if((path.indexOf("{web-context-hash}"))!=-1){
482                            String id=hash(sc);
483                            path=StringUtil.replace(path, "{web-context-hash}", id, false);
484                    }
485            }
486            return path;
487        }
488            
489            public static String hash(ServletContext sc) {
490            String id=null;
491                    try {
492                            id=MD5.getDigestAsString(sc.getRealPath("/"));
493                    } 
494                    catch (IOException e) {}
495                    return id;
496        }
497    
498        public static String getCharset() {
499            return charset;
500        }
501    
502            public static void setCharset(String charset) {
503                    SystemUtil.charset = charset;
504            }
505    
506            public static String getOSSpecificLineSeparator() {
507                    return lineSeparator;
508            }
509    
510            public static void sleep(int time) {
511                    try {
512                            Thread.sleep(time);
513                    } catch (InterruptedException e) {}
514            }
515    
516            public static void sleep(long time) {
517                    try {
518                            Thread.sleep(time);
519                    } catch (InterruptedException e) {}
520            }
521            public static void join(Thread t) {
522                    try {
523                            t.join();
524                    } catch (InterruptedException e) {}
525            }
526            
527            /**
528             * locks the object (synchronized) before calling wait
529             * @param lock
530             * @param timeout
531             * @throws InterruptedException
532             */
533            public static void wait(Object lock, long timeout) {
534                    try {
535                            synchronized (lock) {lock.wait(timeout);}
536                    } catch (InterruptedException e) {}
537            }
538    
539            /**
540             * locks the object (synchronized) before calling wait (no timeout)
541             * @param lock
542             * @throws InterruptedException
543             */
544            public static void wait(Object lock) {
545                    try {
546                            synchronized (lock) {lock.wait();}
547                    } catch (InterruptedException e) {}
548            }
549            
550            
551            
552            /**
553             * locks the object (synchronized) before calling notify
554             * @param lock
555             * @param timeout
556             * @throws InterruptedException
557             */
558            public static void notify(Object lock) {
559                    synchronized (lock) {lock.notify();}
560            }
561            
562            /**
563             * locks the object (synchronized) before calling notifyAll
564             * @param lock
565             * @param timeout
566             * @throws InterruptedException
567             */
568            public static void notifyAll(Object lock) {
569                    synchronized (lock) {lock.notifyAll();}
570            }
571    
572            /**
573             * return the operating system architecture
574             * @return one of the following SystemUtil.ARCH_UNKNOW, SystemUtil.ARCH_32, SystemUtil.ARCH_64
575             */
576            public static int getOSArch(){
577                    if(osArch==-1) {
578                            osArch = toIntArch(System.getProperty("os.arch.data.model"));
579                            if(osArch==ARCH_UNKNOW)osArch = toIntArch(System.getProperty("os.arch"));
580                    }
581                    return osArch;
582            }
583            
584            /**
585             * return the JRE (Java Runtime Engine) architecture, this can be different from the operating system architecture
586             * @return one of the following SystemUtil.ARCH_UNKNOW, SystemUtil.ARCH_32, SystemUtil.ARCH_64
587             */
588            public static int getJREArch(){
589                    if(jreArch==-1) {
590                            jreArch = toIntArch(System.getProperty("sun.arch.data.model"));
591                            if(jreArch==ARCH_UNKNOW)jreArch = toIntArch(System.getProperty("com.ibm.vm.bitmode"));
592                            if(jreArch==ARCH_UNKNOW) {
593                                    int addrSize = getAddressSize();
594                                    if(addrSize==4) return ARCH_32;
595                                    if(addrSize==8) return ARCH_64;
596                            }
597                            
598                    }
599                    return jreArch;
600            }
601            
602            private static int toIntArch(String strArch){
603                    if(!StringUtil.isEmpty(strArch)) {
604                            if(strArch.indexOf("64")!=-1) return ARCH_64;
605                            if(strArch.indexOf("32")!=-1) return ARCH_32;
606                            if(strArch.indexOf("i386")!=-1) return ARCH_32;
607                            if(strArch.indexOf("x86")!=-1) return ARCH_32;
608                    }
609                    return ARCH_UNKNOW;
610            }
611            
612    
613            
614            public static int getAddressSize() {
615                    try {
616                            Class unsafe = ClassUtil.loadClass(null,"sun.misc.Unsafe",null);
617                            if(unsafe==null) return 0;
618                    
619                            Field unsafeField = unsafe.getDeclaredField("theUnsafe");
620                        unsafeField.setAccessible(true);
621                        Object obj = unsafeField.get(null);
622                        Method addressSize = unsafe.getMethod("addressSize", new Class[0]);
623                        
624                        Object res = addressSize.invoke(obj, new Object[0]);
625                        return Caster.toIntValue(res,0);
626                    }
627                    catch(Throwable t){
628                            return 0;
629                    }
630                
631            }
632            private static MemoryUsage getPermGenSpaceSize() {
633                    MemoryUsage mu = getPermGenSpaceSize(null);
634                    if(mu!=null) return mu;
635                    
636                    // create error message including info about available memory blocks
637                    StringBuilder sb=new StringBuilder();
638                    java.util.List<MemoryPoolMXBean> manager = ManagementFactory.getMemoryPoolMXBeans();
639                    Iterator<MemoryPoolMXBean> it = manager.iterator();
640                    MemoryPoolMXBean bean;
641                    while(it.hasNext()){
642                            bean = it.next();
643                            if(sb.length()>0)sb.append(", ");
644                            sb.append(bean.getName());
645                    }
646                    throw new RuntimeException("PermGen Space information not available, available Memory blocks are ["+sb+"]");
647            }
648            
649            private static MemoryUsage getPermGenSpaceSize(MemoryUsage defaultValue) {
650                    if(permGenSpaceBean!=null) return permGenSpaceBean.getUsage();
651                    // create on the fly when the bean is not permanent
652                    MemoryPoolMXBean tmp = getPermGenSpaceBean();
653                    if(tmp!=null) return tmp.getUsage();
654                    
655                    return defaultValue;
656            }
657            
658    
659            public static long getFreePermGenSpaceSize() {
660                    MemoryUsage mu = getPermGenSpaceSize(null);
661                    if(mu==null) return -1;
662                    
663                    long max = mu.getMax();
664                    long used = mu.getUsed();
665                    if(max<0 || used<0) return -1;
666                    return max-used;
667            }
668            
669            public static int getFreePermGenSpacePromille() {
670                    MemoryUsage mu = getPermGenSpaceSize(null);
671                    if(mu==null) return -1;
672                    
673                    long max = mu.getMax();
674                    long used = mu.getUsed();
675                    if(max<0 || used<0) return -1;
676                    return (int)(1000L-(1000L*used/max));
677            }
678            
679            public static Query getMemoryUsage(int type) throws DatabaseException {
680                    
681                    
682                    java.util.List<MemoryPoolMXBean> manager = ManagementFactory.getMemoryPoolMXBeans();
683                    Iterator<MemoryPoolMXBean> it = manager.iterator();
684                    Query qry=new QueryImpl(new Collection.Key[]{
685                                    KeyImpl.NAME,
686                                    KeyImpl.TYPE,
687                                    USED,
688                                    MAX,
689                                    INIT
690                    },0,"memory");
691                    
692                    int row=0;
693                    MemoryPoolMXBean bean;
694                    MemoryUsage usage;
695                    MemoryType _type;
696                    while(it.hasNext()){
697                            bean = it.next();
698                            usage = bean.getUsage();
699                            _type = bean.getType();
700                            if(type==MEMORY_TYPE_HEAP && _type!=MemoryType.HEAP)continue;
701                            if(type==MEMORY_TYPE_NON_HEAP && _type!=MemoryType.NON_HEAP)continue;
702                                    
703                            row++;
704                            qry.addRow();
705                            qry.setAtEL(KeyImpl.NAME, row, bean.getName());
706                            qry.setAtEL(KeyImpl.TYPE, row, _type.name());
707                            qry.setAtEL(MAX, row, Caster.toDouble(usage.getMax()));
708                            qry.setAtEL(USED, row, Caster.toDouble(usage.getUsed()));
709                            qry.setAtEL(INIT, row, Caster.toDouble(usage.getInit()));
710                            
711                    }
712                    return qry;
713            }
714            public static String getPropertyEL(String key) {
715                    try{
716                            String str = System.getProperty(key);
717                            if(!StringUtil.isEmpty(str,true)) return str;
718                            
719                            Iterator<Entry<Object, Object>> it = System.getProperties().entrySet().iterator();
720                            Entry<Object, Object> e;
721                            String n;
722                            while(it.hasNext()){
723                                    e = it.next();
724                                    n=(String) e.getKey();
725                                    if(key.equalsIgnoreCase(n)) return (String) e.getValue();
726                            }
727                            
728                    }
729                    catch(Throwable t){}
730                    return null;
731            }
732            public static long microTime() {
733                    return System.nanoTime()/1000L;
734            }
735    }