001    package railo.runtime.config;
002    
003    import java.io.ByteArrayInputStream;
004    import java.io.ByteArrayOutputStream;
005    import java.io.IOException;
006    import java.io.InputStream;
007    import java.io.PrintWriter;
008    import java.lang.reflect.InvocationTargetException;
009    import java.lang.reflect.Method;
010    import java.util.ArrayList;
011    import java.util.HashMap;
012    import java.util.Iterator;
013    import java.util.LinkedHashMap;
014    import java.util.Locale;
015    import java.util.Map;
016    import java.util.Map.Entry;
017    import java.util.TimeZone;
018    
019    import javax.servlet.ServletConfig;
020    
021    import org.apache.xerces.parsers.DOMParser;
022    import org.jfree.chart.block.LabelBlockImpl;
023    import org.safehaus.uuid.UUIDGenerator;
024    import org.slf4j.impl.StaticLoggerBinder;
025    import org.w3c.dom.Document;
026    import org.w3c.dom.Element;
027    import org.w3c.dom.Node;
028    import org.w3c.dom.NodeList;
029    import org.xml.sax.InputSource;
030    import org.xml.sax.SAXException;
031    
032    import railo.aprint;
033    import railo.print;
034    import railo.commons.collections.HashTable;
035    import railo.commons.date.TimeZoneUtil;
036    import railo.commons.digest.MD5;
037    import railo.commons.io.DevNullOutputStream;
038    import railo.commons.io.FileUtil;
039    import railo.commons.io.IOUtil;
040    import railo.commons.io.SystemUtil;
041    import railo.commons.io.log.Log;
042    import railo.commons.io.log.LogAndSource;
043    import railo.commons.io.log.LogUtil;
044    import railo.commons.io.res.Resource;
045    import railo.commons.io.res.ResourcesImpl;
046    import railo.commons.io.res.type.cfml.CFMLResourceProvider;
047    import railo.commons.io.res.type.s3.S3ResourceProvider;
048    import railo.commons.io.res.util.ResourceClassLoader;
049    import railo.commons.io.res.util.ResourceUtil;
050    import railo.commons.lang.ByteSizeParser;
051    import railo.commons.lang.ClassException;
052    import railo.commons.lang.ClassLoaderHelper;
053    import railo.commons.lang.ClassUtil;
054    import railo.commons.lang.Md5;
055    import railo.commons.lang.StringUtil;
056    import railo.commons.lang.SystemOut;
057    import railo.commons.net.URLDecoder;
058    import railo.loader.TP;
059    import railo.loader.engine.CFMLEngineFactory;
060    import railo.runtime.CFMLFactoryImpl;
061    import railo.runtime.Component;
062    import railo.runtime.Info;
063    import railo.runtime.Mapping;
064    import railo.runtime.MappingImpl;
065    import railo.runtime.cache.CacheConnection;
066    import railo.runtime.cache.CacheConnectionImpl;
067    import railo.runtime.cache.ServerCacheConnection;
068    import railo.runtime.cache.eh.EHCacheLite;
069    import railo.runtime.cfx.customtag.CFXTagClass;
070    import railo.runtime.cfx.customtag.CPPCFXTagClass;
071    import railo.runtime.cfx.customtag.JavaCFXTagClass;
072    import railo.runtime.component.ImportDefintion;
073    import railo.runtime.config.ajax.AjaxFactory;
074    import railo.runtime.config.component.ComponentFactory;
075    import railo.runtime.crypt.BlowfishEasy;
076    import railo.runtime.db.DataSource;
077    import railo.runtime.db.DataSourceImpl;
078    import railo.runtime.dump.ClassicHTMLDumpWriter;
079    import railo.runtime.dump.DumpWriter;
080    import railo.runtime.dump.DumpWriterEntry;
081    import railo.runtime.dump.HTMLDumpWriter;
082    import railo.runtime.dump.SimpleHTMLDumpWriter;
083    import railo.runtime.dump.TextDumpWriter;
084    import railo.runtime.engine.CFMLEngineImpl;
085    import railo.runtime.engine.ConsoleExecutionLog;
086    import railo.runtime.engine.ExecutionLog;
087    import railo.runtime.engine.ExecutionLogFactory;
088    import railo.runtime.engine.ThreadLocalConfig;
089    import railo.runtime.engine.ThreadQueueImpl;
090    import railo.runtime.exp.ApplicationException;
091    import railo.runtime.exp.ExpressionException;
092    import railo.runtime.exp.PageException;
093    import railo.runtime.exp.SecurityException;
094    import railo.runtime.extension.Extension;
095    import railo.runtime.extension.ExtensionImpl;
096    import railo.runtime.extension.ExtensionProvider;
097    import railo.runtime.extension.ExtensionProviderImpl;
098    import railo.runtime.functions.other.CreateUUID;
099    import railo.runtime.gateway.GatewayEngineImpl;
100    import railo.runtime.gateway.GatewayEntry;
101    import railo.runtime.gateway.GatewayEntryImpl;
102    import railo.runtime.listener.AppListenerUtil;
103    import railo.runtime.listener.ApplicationListener;
104    import railo.runtime.listener.ClassicAppListener;
105    import railo.runtime.listener.MixedAppListener;
106    import railo.runtime.listener.ModernAppListener;
107    import railo.runtime.listener.NoneAppListener;
108    import railo.runtime.monitor.ActionMonitorCollector;
109    import railo.runtime.monitor.ActionMonitorFatory;
110    import railo.runtime.monitor.IntervallMonitor;
111    import railo.runtime.monitor.IntervallMonitorWrap;
112    import railo.runtime.monitor.RequestMonitor;
113    import railo.runtime.monitor.RequestMonitorWrap;
114    import railo.runtime.net.http.ReqRspUtil;
115    import railo.runtime.net.mail.Server;
116    import railo.runtime.net.mail.ServerImpl;
117    import railo.runtime.net.proxy.ProxyData;
118    import railo.runtime.net.proxy.ProxyDataImpl;
119    import railo.runtime.op.Caster;
120    import railo.runtime.op.date.DateCaster;
121    import railo.runtime.orm.ORMConfiguration;
122    import railo.runtime.orm.ORMConfigurationImpl;
123    import railo.runtime.orm.ORMEngine;
124    import railo.runtime.orm.hibernate.HibernateORMEngine;
125    import railo.runtime.reflection.Reflector;
126    import railo.runtime.reflection.pairs.ConstructorInstance;
127    import railo.runtime.search.SearchEngine;
128    import railo.runtime.security.SecurityManager;
129    import railo.runtime.security.SecurityManagerImpl;
130    import railo.runtime.spooler.SpoolerEngineImpl;
131    import railo.runtime.tag.TagUtil;
132    import railo.runtime.text.xml.XMLCaster;
133    import railo.runtime.type.KeyImpl;
134    import railo.runtime.type.Struct;
135    import railo.runtime.type.StructImpl;
136    import railo.runtime.type.dt.TimeSpan;
137    import railo.runtime.type.scope.Cluster;
138    import railo.runtime.type.scope.ClusterRemote;
139    import railo.runtime.type.scope.Undefined;
140    import railo.runtime.type.util.ArrayUtil;
141    import railo.runtime.type.util.KeyConstants;
142    import railo.runtime.type.util.ListUtil;
143    import railo.runtime.video.VideoExecuter;
144    import railo.transformer.library.function.FunctionLib;
145    import railo.transformer.library.function.FunctionLibException;
146    import railo.transformer.library.tag.TagLib;
147    import railo.transformer.library.tag.TagLibException;
148    
149    import com.jacob.com.LibraryLoader;
150    
151    /**
152     * 
153     */
154    public final class ConfigWebFactory {
155            /**
156             * creates a new ServletConfig Impl Object
157             * 
158             * @param configServer
159             * @param configDir
160             * @param servletConfig
161             * @return new Instance
162             * @throws SAXException
163             * @throws ClassNotFoundException
164             * @throws PageException
165             * @throws IOException
166             * @throws TagLibException
167             * @throws FunctionLibException
168             */
169    
170            public static ConfigWebImpl newInstance(CFMLFactoryImpl factory, ConfigServerImpl configServer, Resource configDir, boolean isConfigDirACustomSetting,
171                            ServletConfig servletConfig) throws SAXException, ClassException, PageException, IOException, TagLibException, FunctionLibException {
172                    // DO NOT REMOVE!!!!
173                    try {
174                            new LabelBlockImpl("aa");
175                    }
176                    catch (Throwable t) {
177    
178                    }
179    
180                    String hash = SystemUtil.hash(servletConfig.getServletContext());
181                    Map<String, String> labels = configServer.getLabels();
182                    String label = null;
183                    if (labels != null) {
184                            label = labels.get(hash);
185                    }
186                    if (label == null)
187                            label = hash;
188    
189                    SystemOut.print(SystemUtil.getPrintWriter(SystemUtil.OUT), "===================================================================\n" + "WEB CONTEXT (" + label + ")\n"
190                                    + "-------------------------------------------------------------------\n" + "- config:" + configDir + (isConfigDirACustomSetting ? " (custom setting)" : "") + "\n"
191                                    + "- webroot:" + ReqRspUtil.getRootPath(servletConfig.getServletContext()) + "\n" + "- hash:" + hash + "\n" + "- label:" + label + "\n"
192                                    + "===================================================================\n"
193    
194                    );
195    
196                    boolean doNew = doNew(configDir);
197    
198                    Resource configFile = configDir.getRealResource("railo-web.xml.cfm");
199                    Resource configFileOld = configDir.getRealResource("railo-web.xml");
200    
201                    String strPath = servletConfig.getServletContext().getRealPath("/WEB-INF");
202                    Resource path = ResourcesImpl.getFileResourceProvider().getResource(strPath);
203    
204                    // get config file
205                    if (!configFile.exists()) {
206                            if (configFileOld.exists()) {
207                                    // if(!configFileOld.renameTo(configFile))
208                                    configFile = configFileOld;
209                            }
210                            else
211                                    createConfigFile("web", configFile);
212                    }
213                    Document doc = null;
214    
215                    Resource bugFile;
216                    int count = 1;
217                    // rename old bugfiles
218                    while ((bugFile = configDir.getRealResource("railo-web." + (count++) + ".buggy.cfm")).exists()) {
219                            bugFile.renameTo(configDir.getRealResource("railo-web." + (count) + ".buggy"));
220                    }
221    
222                    try {
223                            doc = loadDocument(configFile);
224                    }
225                    catch (Exception e) {
226                            // rename buggy config files
227                            if (configFile.exists()) {
228                                    SystemOut.printDate(SystemUtil.getPrintWriter(SystemUtil.OUT), "config file " + configFile + " was not valid and has been replaced");
229                                    count = 1;
230                                    while ((bugFile = configDir.getRealResource("railo-web." + (count++) + ".buggy")).exists()) {
231                                    }
232                                    IOUtil.copy(configFile, bugFile);
233                                    configFile.delete();
234                            }
235                            createConfigFile("web", configFile);
236                            doc = loadDocument(configFile);
237                    }
238    
239                    // htaccess
240                    if (path.exists())
241                            createHtAccess(path.getRealResource(".htaccess"));
242                    if (configDir.exists())
243                            createHtAccess(configDir.getRealResource(".htaccess"));
244    
245                    createContextFiles(configDir, servletConfig, doNew);
246                    ConfigWebImpl configWeb = new ConfigWebImpl(factory, configServer, servletConfig, configDir, configFile);
247    
248                    load(configServer, configWeb, doc, false, doNew);
249                    createContextFilesPost(configDir, configWeb, servletConfig, false, doNew);
250                    return configWeb;
251            }
252    
253            public static void createHtAccess(Resource htAccess) {
254                    if (!htAccess.exists()) {
255                            htAccess.createNewFile();
256    
257                            String content = "AuthName \"WebInf Folder\"\n" + "AuthType Basic\n" + "<Limit GET POST>\n" + "order deny,allow\n" + "deny from all\n" + "</Limit>";
258                            try {
259                                    IOUtil.copy(new ByteArrayInputStream(content.getBytes()), htAccess, true);
260                            }
261                            catch (Throwable t) {
262                            }
263                    }
264            }
265    
266            /**
267             * reloads the Config Object
268             * 
269             * @param config
270             * @param force
271             * @throws SAXException
272             * @throws ClassNotFoundException
273             * @throws PageException
274             * @throws IOException
275             * @throws TagLibException
276             * @throws FunctionLibException
277             */
278            public static void reloadInstance(ConfigServerImpl cs, ConfigWebImpl cw, boolean force) throws SAXException, ClassException, PageException, IOException, TagLibException,
279                            FunctionLibException {
280                    Resource configFile = cw.getConfigFile();
281                    Resource configDir = cw.getConfigDir();
282    
283                    boolean doNew = doNew(configDir);
284    
285                    if (configFile == null)
286                            return;
287    
288                    if (second(cw.getLoadTime()) > second(configFile.lastModified()) && !force)
289                            return;
290    
291                    Document doc = loadDocument(configFile);
292                    createContextFiles(configDir, null, doNew);
293                    cw.reset();
294    
295                    load(cs, cw, doc, true, doNew);
296                    createContextFilesPost(configDir, cw, null, false, doNew);
297            }
298    
299            private static long second(long ms) {
300                    return ms / 1000;
301            }
302    
303            /**
304             * @param configServer
305             * @param config
306             * @param doc
307             * @throws ClassNotFoundException
308             * @throws IOException
309             * @throws FunctionLibException
310             * @throws TagLibException
311             * @throws PageException
312             */
313            public static void load(ConfigServerImpl cs, ConfigImpl config, Document doc, boolean isReload, boolean doNew) throws ClassException, PageException, IOException,
314                            TagLibException, FunctionLibException {
315                    ThreadLocalConfig.register(config);
316                    // fix
317                    if (ConfigWebAdmin.fixS3(doc) || ConfigWebAdmin.fixPSQ(doc)) {
318                            XMLCaster.writeTo(doc, config.getConfigFile());
319                            try {
320                                    doc = ConfigWebFactory.loadDocument(config.getConfigFile());
321                            }
322                            catch (SAXException e) {
323                            }
324                    }
325    
326                    config.setLastModified();
327    
328                    loadRailoConfig(cs, config, doc);
329                    int mode = config.getMode();
330                    loadConstants(cs, config, doc);
331                    loadTempDirectory(cs, config, doc, isReload);
332                    loadId(config);
333                    loadVersion(config, doc);
334                    loadSecurity(cs, config, doc);
335                    loadLib(cs, config);
336                    loadSystem(cs, config, doc);
337                    loadORM(cs, config, doc);
338                    loadResourceProvider(cs, config, doc);
339                    loadCharset(cs, config, doc);
340                    loadApplication(cs, config, doc, mode);
341                    loadMappings(cs, config, doc, mode); // it is important this runs after
342                                                                                                    // loadApplication
343                    loadRest(cs, config, doc);
344                    loadExtensions(cs, config, doc);
345                    loadPagePool(cs, config, doc);
346                    loadDataSources(cs, config, doc);
347                    loadCache(cs, config, doc);
348                    loadCustomTagsMappings(cs, config, doc, mode);
349                    loadFilesystem(cs, config, doc, doNew); // load tlds
350                    loadTag(cs, config, doc); // load tlds
351                    loadRegional(cs, config, doc);
352                    loadCompiler(cs, config, doc, mode);
353                    loadScope(cs, config, doc, mode);
354                    loadMail(cs, config, doc);
355                    loadSearch(cs, config, doc);
356                    loadScheduler(cs, config, doc);
357                    loadDebug(cs, config, doc);
358                    loadError(cs, config, doc);
359                    loadCFX(cs, config, doc);
360                    loadComponent(cs, config, doc, mode);
361                    loadUpdate(cs, config, doc);
362                    loadJava(cs, config, doc); // define compile type
363                    loadSetting(cs, config, doc);
364                    loadProxy(cs, config, doc);
365                    loadRemoteClient(cs, config, doc);
366                    loadVideo(cs, config, doc);
367                    loadFlex(cs, config, doc);
368                    settings(config);
369                    loadListener(cs, config, doc);
370                    loadDumpWriter(cs, config, doc);
371                    loadGatewayEL(cs, config, doc);
372                    loadExeLog(cs, config, doc);
373                    loadThreadQueue(cs, config, doc);
374                    loadMonitors(cs, config, doc);
375                    loadLogin(cs, config, doc);
376                    config.setLoadTime(System.currentTimeMillis());
377    
378                    // this call is needed to make sure the railo StaticLoggerBinder is
379                    // loaded
380                    try {
381                            StaticLoggerBinder.getSingleton();
382                    }
383                    catch (Throwable t) {
384                    }
385    
386                    if (config instanceof ConfigWebImpl)
387                            TagUtil.addTagMetaData((ConfigWebImpl) config);
388    
389                    ThreadLocalConfig.release();
390            }
391    
392            private static void loadResourceProvider(ConfigServerImpl configServer, ConfigImpl config, Document doc) throws ClassException {
393                    boolean hasCS = configServer != null;
394                    config.clearResourceProviders();
395                    Element resources = getChildByName(doc.getDocumentElement(), "resources");
396                    Element[] providers = getChildren(resources, "resource-provider");
397                    Element[] defaultProviders = getChildren(resources, "default-resource-provider");
398    
399                    // Default Resource Provider
400                    if (hasCS)
401                            config.setDefaultResourceProvider(configServer.getDefaultResourceProvider());
402                    if (defaultProviders != null && defaultProviders.length > 0) {
403                            Element defaultProvider = defaultProviders[defaultProviders.length - 1];
404                            String strDefaultProviderClass = defaultProvider.getAttribute("class");
405                            String strDefaultProviderComponent = defaultProvider.getAttribute("component");
406    
407                            // class
408                            if (!StringUtil.isEmpty(strDefaultProviderClass)) {
409                                    strDefaultProviderClass = strDefaultProviderClass.trim();
410                                    config.setDefaultResourceProvider(strDefaultProviderClass, toArguments(defaultProvider.getAttribute("arguments"), true));
411                            }
412    
413                            // component
414                            else if (!StringUtil.isEmpty(strDefaultProviderComponent)) {
415                                    strDefaultProviderComponent = strDefaultProviderComponent.trim();
416                                    Map<String, String> args = toArguments(defaultProvider.getAttribute("arguments"), true);
417                                    args.put("component", strDefaultProviderComponent);
418                                    config.setDefaultResourceProvider(CFMLResourceProvider.class.getName(), args);
419                            }
420                    }
421    
422                    // Resource Provider
423                    if (hasCS)
424                            config.setResourceProviders(configServer.getResourceProviders());
425                    if (providers != null && providers.length > 0) {
426    
427                            String strProviderClass;
428                            String strProviderCFC;
429                            String strProviderScheme;
430                            String httpClass = null;
431                            Map httpArgs = null;
432                            boolean hasHTTPs = false, hasS3 = false;
433                            String s3Class = "railo.commons.io.res.type.s3.S3ResourceProvider";
434                            for (int i = 0; i < providers.length; i++) {
435                                    strProviderClass = providers[i].getAttribute("class");
436                                    strProviderCFC = providers[i].getAttribute("component");
437    
438                                    // ignore S3 extension
439                                    if ("railo.extension.io.resource.type.s3.S3ResourceProvider".equals(strProviderClass))
440                                            strProviderClass = S3ResourceProvider.class.getName();
441    
442                                    strProviderScheme = providers[i].getAttribute("scheme");
443                                    // class
444                                    if (!StringUtil.isEmpty(strProviderClass) && !StringUtil.isEmpty(strProviderScheme)) {
445                                            strProviderClass = strProviderClass.trim();
446                                            strProviderScheme = strProviderScheme.trim().toLowerCase();
447                                            config.addResourceProvider(strProviderScheme, strProviderClass, toArguments(providers[i].getAttribute("arguments"), true));
448    
449                                            // patch for user not having
450                                            if (strProviderScheme.equalsIgnoreCase("http")) {
451                                                    httpClass = strProviderClass;
452                                                    httpArgs = toArguments(providers[i].getAttribute("arguments"), true);
453                                            }
454                                            else if (strProviderScheme.equalsIgnoreCase("https"))
455                                                    hasHTTPs = true;
456                                            else if (strProviderScheme.equalsIgnoreCase("s3"))
457                                                    hasS3 = true;
458                                    }
459    
460                                    // cfc
461                                    else if (!StringUtil.isEmpty(strProviderCFC) && !StringUtil.isEmpty(strProviderScheme)) {
462                                            strProviderCFC = strProviderCFC.trim();
463                                            strProviderScheme = strProviderScheme.trim().toLowerCase();
464                                            Map<String, String> args = toArguments(providers[i].getAttribute("arguments"), true);
465                                            args.put("component", strProviderCFC);
466                                            config.addResourceProvider(strProviderScheme, CFMLResourceProvider.class, args);
467                                    }
468                            }
469    
470                            // adding https when not exist
471                            if (!hasHTTPs && httpClass != null) {
472                                    config.addResourceProvider("https", httpClass, httpArgs);
473                            }
474                            // adding s3 when not exist
475                            if (!hasS3 && config instanceof ConfigServer) {
476                                    config.addResourceProvider("s3", s3Class, toArguments("lock-timeout:10000;", false));
477                            }
478                    }
479            }
480    
481            private static void loadDumpWriter(ConfigServerImpl configServer, ConfigImpl config, Document doc) throws ClassException {
482                    boolean hasCS = configServer != null;
483    
484                    Element coll = getChildByName(doc.getDocumentElement(), "dump-writers");
485                    Element[] writers = getChildren(coll, "dump-writer");
486    
487                    Struct sct = new StructImpl();
488    
489                    boolean hasPlain = false;
490                    boolean hasRich = false;
491                    if (hasCS) {
492                            DumpWriterEntry[] entries = configServer.getDumpWritersEntries();
493                            if (entries != null)
494                                    for (int i = 0; i < entries.length; i++) {
495                                            if (entries[i].getDefaultType() == HTMLDumpWriter.DEFAULT_PLAIN)
496                                                    hasPlain = true;
497                                            if (entries[i].getDefaultType() == HTMLDumpWriter.DEFAULT_RICH)
498                                                    hasRich = true;
499                                            sct.put(entries[i].getName(), entries[i]);
500                                    }
501                    }
502    
503                    if (writers != null && writers.length > 0) {
504                            String strClass;
505                            String strName;
506                            String strDefault;
507                            Class clazz;
508                            int def = HTMLDumpWriter.DEFAULT_NONE;
509                            for (int i = 0; i < writers.length; i++) {
510                                    strClass = writers[i].getAttribute("class");
511                                    strName = writers[i].getAttribute("name");
512                                    strDefault = writers[i].getAttribute("default");
513                                    clazz = ClassUtil.loadClass(strClass, null);
514                                    if (clazz != null && !StringUtil.isEmpty(strName)) {
515                                            if (StringUtil.isEmpty(strDefault))
516                                                    def = HTMLDumpWriter.DEFAULT_NONE;
517                                            else if ("browser".equalsIgnoreCase(strDefault))
518                                                    def = HTMLDumpWriter.DEFAULT_RICH;
519                                            else if ("console".equalsIgnoreCase(strDefault))
520                                                    def = HTMLDumpWriter.DEFAULT_PLAIN;
521                                            sct.put(strName, new DumpWriterEntry(def, strName, (DumpWriter) ClassUtil.loadInstance(clazz)));
522                                    }
523                            }
524                    }
525                    else {
526                            // print.err("yep");
527                            if (!hasRich)
528                                    sct.setEL(KeyConstants._html, new DumpWriterEntry(HTMLDumpWriter.DEFAULT_RICH, "html", new HTMLDumpWriter()));
529                            if (!hasPlain)
530                                    sct.setEL(KeyConstants._text, new DumpWriterEntry(HTMLDumpWriter.DEFAULT_PLAIN, "text", new TextDumpWriter()));
531    
532                            sct.setEL(KeyConstants._classic, new DumpWriterEntry(HTMLDumpWriter.DEFAULT_NONE, "classic", new ClassicHTMLDumpWriter()));
533                            sct.setEL(KeyConstants._simple, new DumpWriterEntry(HTMLDumpWriter.DEFAULT_NONE, "simple", new SimpleHTMLDumpWriter()));
534    
535                    }
536                    Iterator<Object> it = sct.valueIterator();
537                    java.util.List<DumpWriterEntry> entries = new ArrayList<DumpWriterEntry>();
538                    while (it.hasNext()) {
539                            entries.add((DumpWriterEntry) it.next());
540                    }
541                    config.setDumpWritersEntries(entries.toArray(new DumpWriterEntry[entries.size()]));
542            }
543    
544            static Map<String, String> toArguments(String attributes, boolean decode) {
545                    Map<String, String> map = new HashMap<String, String>();
546                    if (attributes == null)
547                            return map;
548                    String[] arr = ListUtil.toStringArray(ListUtil.listToArray(attributes, ';'), null);
549    
550                    int index;
551                    String str;
552                    for (int i = 0; i < arr.length; i++) {
553                            str = arr[i].trim();
554                            if (StringUtil.isEmpty(str))
555                                    continue;
556                            index = str.indexOf(':');
557                            if (index == -1)
558                                    map.put(str, "");
559                            else {
560                                    map.put(dec(str.substring(0, index).trim(), decode), dec(str.substring(index + 1).trim(), decode));
561                            }
562                    }
563                    return map;
564            }
565    
566            private static String dec(String str, boolean decode) {
567                    if (!decode)
568                            return str;
569                    return URLDecoder.decode(str, false);
570            }
571    
572            private static void loadListener(ConfigServerImpl configServer, ConfigImpl config, Document doc) {
573                    if (config instanceof ConfigServer) {
574                            ConfigServer cs = (ConfigServer) config;
575                            Element listener = getChildByName(doc.getDocumentElement(), "listener");
576                            String strClass = listener.getAttribute("class");
577                            String strArguments = listener.getAttribute("arguments");
578                            if (strArguments == null)
579                                    strArguments = "";
580    
581                            if (!StringUtil.isEmpty(strClass)) {
582                                    try {
583    
584                                            Object obj = ClassUtil.loadInstance(strClass, new Object[] { strArguments }, null);
585                                            if (obj instanceof ConfigListener) {
586                                                    ConfigListener cl = (ConfigListener) obj;
587                                                    cs.setConfigListener(cl);
588                                            }
589                                    }
590                                    catch (Throwable t) {
591                                            t.printStackTrace(config.getErrWriter());
592    
593                                    }
594    
595                            }
596                    }
597                    else if (configServer != null) {
598                            ConfigListener listener = configServer.getConfigListener();
599                            if (listener != null)
600                                    listener.onLoadWebContext(configServer, (ConfigWeb) config);
601                    }
602            }
603    
604            private static void settings(ConfigImpl config) {
605                    if (!(config instanceof ConfigServer))
606                            doCheckChangesInLibraries(config);
607    
608            }
609    
610            private static void loadVersion(ConfigImpl config, Document doc) {
611                    Element railoConfiguration = doc.getDocumentElement();
612                    String strVersion = railoConfiguration.getAttribute("version");
613                    config.setVersion(Caster.toDoubleValue(strVersion, 1.0d));
614            }
615    
616            private static void loadId(ConfigImpl config) {
617                    Resource res = config.getConfigDir().getRealResource("id");
618                    String securityKey = null;
619                    try {
620                            if (!res.exists()) {
621                                    res.createNewFile();
622                                    IOUtil.write(res, securityKey = UUIDGenerator.getInstance().generateRandomBasedUUID().toString(), SystemUtil.getCharset(), false);
623                            }
624                            else {
625                                    securityKey = IOUtil.toString(res, SystemUtil.getCharset());
626                            }
627                    }
628                    catch (IOException ioe) {
629                    }
630    
631                    if (StringUtil.isEmpty(securityKey))
632                            securityKey = UUIDGenerator.getInstance().generateRandomBasedUUID().toString();
633    
634                    config.setSecurityKey(securityKey);
635            }
636    
637            public static void reloadLib(ConfigImpl config) throws IOException {
638                    if (config instanceof ConfigWebImpl)
639                            loadLib(((ConfigWebImpl) config).getConfigServerImpl(), config);
640                    else
641                            loadLib(null, config);
642            }
643    
644            private static void loadLib(ConfigServerImpl configServer, ConfigImpl config) throws IOException {
645                    // get lib and classes resources
646                    Resource lib = config.getConfigDir().getRealResource("lib");
647                    lib.mkdir();
648                    Resource classes = config.getConfigDir().getRealResource("classes");
649                    classes.mkdir();
650                    Resource[] libs = lib.listResources();
651    
652                    // merge resources
653                    if (libs.length > 0 || !ResourceUtil.isEmptyDirectory(classes)) {
654                            Resource[] tmp = new Resource[libs.length + 1];
655                            for (int i = 0; i < libs.length; i++) {
656                                    tmp[i] = libs[i];
657                            }
658                            tmp[libs.length] = classes;
659                            libs = tmp;
660                    }
661                    else {
662                            libs = new Resource[0];
663                    }
664    
665                    // get resources from server config and merge
666                    if (configServer != null) {
667                            ResourceClassLoader rcl = configServer.getResourceClassLoader();
668                            libs = ResourceUtil.merge(libs, rcl.getResources());
669                    }
670    
671                    // get parent classloader
672                    // ClassLoader parent;
673                    // if(configServer==null) parent=new
674                    // ClassLoaderHelper().getClass().getClassLoader();// this classloader
675                    // holds all loader and core classes
676                    // else parent = configServer.getResourceClassLoader(); // Resource
677                    // classloader from server config
678    
679                    // set classloader
680                    ClassLoader parent = new ClassLoaderHelper().getClass().getClassLoader();// this
681                                                                                                                                                                            // classloader
682                                                                                                                                                                            // holds
683                                                                                                                                                                            // all
684                                                                                                                                                                            // loader
685                                                                                                                                                                            // and
686                                                                                                                                                                            // core
687                                                                                                                                                                            // classes
688                    config.setResourceClassLoader(new ResourceClassLoader(libs, parent));
689    
690            }
691    
692            private static boolean equal(Resource[] srcs, Resource[] trgs) {
693                    if (srcs.length != trgs.length)
694                            return false;
695                    Resource src;
696                    outer: for (int i = 0; i < srcs.length; i++) {
697                            src = srcs[i];
698                            for (int y = 0; y < trgs.length; y++) {
699                                    if (src.equals(trgs[y]))
700                                            continue outer;
701                            }
702                            return false;
703                    }
704                    return true;
705            }
706    
707            private static Resource[] getNewResources(Resource[] srcs, Resource[] trgs) {
708                    Resource trg;
709                    java.util.List<Resource> list = new ArrayList<Resource>();
710                    outer: for (int i = 0; i < trgs.length; i++) {
711                            trg = trgs[i];
712                            for (int y = 0; y < srcs.length; y++) {
713                                    if (trg.equals(srcs[y]))
714                                            continue outer;
715                            }
716                            list.add(trg);
717                    }
718                    return list.toArray(new Resource[list.size()]);
719            }
720    
721            /**
722             * @param configServer
723             * @param config
724             * @param doc
725             */
726            private static void loadSecurity(ConfigServerImpl configServer, ConfigImpl config, Document doc) {
727    
728                    // Serial Number
729                    if (config instanceof ConfigServer) {
730                            Element railoConfiguration = doc.getDocumentElement();
731                            String serial = railoConfiguration.getAttribute("serial-number");
732                            if (!StringUtil.isEmpty(serial))
733                                    config.setSerialNumber(serial);
734                    }
735                    else if (configServer != null) {
736                            config.setSerialNumber(configServer.getSerialNumber());
737                    }
738    
739                    // Security Manger
740                    SecurityManager securityManager = null;
741                    if (config instanceof ConfigServerImpl) {
742                            ConfigServerImpl cs = (ConfigServerImpl) config;
743                            Element security = getChildByName(doc.getDocumentElement(), "security");
744    
745                            // Default SecurityManager
746                            SecurityManagerImpl sm = _toSecurityManager(security);
747    
748                            // addional file accesss directories
749                            Element[] elFileAccesses = getChildren(security, "file-access");
750                            sm.setCustomFileAccess(_loadFileAccess(config, elFileAccesses));
751    
752                            cs.setDefaultSecurityManager(sm);
753    
754                            // Web SecurityManager
755                            Element[] accessors = getChildren(security, "accessor");
756                            for (int i = 0; i < accessors.length; i++) {
757                                    String id = accessors[i].getAttribute("id");
758                                    if (id != null) {
759                                            sm = _toSecurityManager(accessors[i]);
760                                            elFileAccesses = getChildren(accessors[i], "file-access");
761                                            sm.setCustomFileAccess(_loadFileAccess(config, elFileAccesses));
762                                            cs.setSecurityManager(id, sm);
763                                    }
764                            }
765    
766                    }
767    
768                    else if (configServer != null) {
769                            securityManager = configServer.getSecurityManager(config.getId());
770                    }
771                    if (config instanceof ConfigWebImpl) {
772                            if (securityManager == null)
773                                    securityManager = SecurityManagerImpl.getOpenSecurityManager();
774                            ((ConfigWebImpl) config).setSecurityManager(securityManager);
775                    }
776            }
777    
778            private static Resource[] _loadFileAccess(Config config, Element[] fileAccesses) {
779                    if (ArrayUtil.isEmpty(fileAccesses))
780                            return new Resource[0];
781    
782                    java.util.List<Resource> reses = new ArrayList<Resource>();
783                    String path;
784                    Resource res;
785                    for (int i = 0; i < fileAccesses.length; i++) {
786                            path = fileAccesses[i].getAttribute("path");
787                            if (!StringUtil.isEmpty(path)) {
788                                    res = config.getResource(path);
789                                    if (res.isDirectory())
790                                            reses.add(res);
791                            }
792                    }
793                    return reses.toArray(new Resource[reses.size()]);
794            }
795    
796            private static SecurityManagerImpl _toSecurityManager(Element el) {
797                    SecurityManagerImpl sm = new SecurityManagerImpl(_attr(el, "setting", SecurityManager.VALUE_YES), _attr(el, "file", SecurityManager.VALUE_ALL), _attr(el,
798                                    "direct_java_access", SecurityManager.VALUE_YES), _attr(el, "mail", SecurityManager.VALUE_YES), _attr(el, "datasource", SecurityManager.VALUE_YES), _attr(el,
799                                    "mapping", SecurityManager.VALUE_YES), _attr(el, "remote", SecurityManager.VALUE_YES), _attr(el, "custom_tag", SecurityManager.VALUE_YES), _attr(el, "cfx_setting",
800                                    SecurityManager.VALUE_YES), _attr(el, "cfx_usage", SecurityManager.VALUE_YES), _attr(el, "debugging", SecurityManager.VALUE_YES), _attr(el, "search",
801                                    SecurityManager.VALUE_YES), _attr(el, "scheduled_task", SecurityManager.VALUE_YES), _attr(el, "tag_execute", SecurityManager.VALUE_YES), _attr(el, "tag_import",
802                                    SecurityManager.VALUE_YES), _attr(el, "tag_object", SecurityManager.VALUE_YES), _attr(el, "tag_registry", SecurityManager.VALUE_YES), _attr(el, "cache",
803                                    SecurityManager.VALUE_YES), _attr(el, "gateway", SecurityManager.VALUE_YES), _attr(el, "orm", SecurityManager.VALUE_YES), _attr2(el, "access_read",
804                                    SecurityManager.ACCESS_PROTECTED), _attr2(el, "access_write", SecurityManager.ACCESS_PROTECTED));
805                    return sm;
806            }
807    
808            private static short _attr(Element el, String attr, short _default) {
809                    return SecurityManagerImpl.toShortAccessValue(el.getAttribute(attr), _default);
810            }
811    
812            private static short _attr2(Element el, String attr, short _default) {
813                    String strAccess = el.getAttribute(attr);
814                    if (StringUtil.isEmpty(strAccess))
815                            return _default;
816                    strAccess = strAccess.trim().toLowerCase();
817                    if ("open".equals(strAccess))
818                            return SecurityManager.ACCESS_OPEN;
819                    if ("protected".equals(strAccess))
820                            return SecurityManager.ACCESS_PROTECTED;
821                    if ("close".equals(strAccess))
822                            return SecurityManager.ACCESS_CLOSE;
823                    return _default;
824            }
825    
826            /**
827             * load XML Document from XML File
828             * 
829             * @param xmlFile
830             *            XML File to read
831             * @return returns the Document
832             * @throws SAXException
833             * @throws IOException
834             */
835            static Document loadDocument(Resource xmlFile) throws SAXException, IOException {
836    
837                    InputStream is = null;
838                    try {
839                            return _loadDocument(is = IOUtil.toBufferedInputStream(xmlFile.getInputStream()));
840                    }
841                    finally {
842                            IOUtil.closeEL(is);
843                    }
844            }
845    
846            /**
847             * load XML Document from XML File
848             * 
849             * @param is
850             *            InoutStream to read
851             * @return returns the Document
852             * @throws SAXException
853             * @throws IOException
854             */
855            private static Document _loadDocument(InputStream is) throws SAXException, IOException {
856                    DOMParser parser = new DOMParser();
857                    InputSource source = new InputSource(is);
858                    parser.parse(source);
859                    is.close();
860                    return parser.getDocument();
861            }
862    
863            /**
864             * creates the Config File, if File not exist
865             * 
866             * @param xmlName
867             * @param configFile
868             * @throws IOException
869             */
870            static void createConfigFile(String xmlName, Resource configFile) throws IOException {
871                    configFile.createFile(true);
872                    createFileFromResource("/resource/config/" + xmlName + ".xml", configFile.getAbsoluteResource());
873            }
874    
875            /**
876             * creates a File and his content froma a resurce
877             * 
878             * @param resource
879             * @param file
880             * @throws IOException
881             */
882            static void createFileFromResource(String resource, Resource file) throws IOException {
883                    createFileFromResource(resource, file, null);
884            }
885    
886            public static void createFileFromResourceEL(String resource, Resource file) {
887                    try {
888                            createFileFromResource(resource, file, null);
889                    }
890                    catch (Throwable e) {
891                    }
892            }
893    
894            /**
895             * creates a File and his content froma a resurce
896             * 
897             * @param resource
898             * @param file
899             * @param password
900             * @throws IOException
901             */
902            static void createFileFromResource(String resource, Resource file, String password) throws IOException {
903                    SystemOut.printDate(SystemUtil.getPrintWriter(SystemUtil.OUT), "write file:" + file);
904                    file.createNewFile();
905                    IOUtil.copy(new Info().getClass().getResourceAsStream(resource), file, true);
906            }
907    
908            static String createMD5FromResource(String resource) throws IOException {
909                    InputStream is = null;
910                    try {
911                            is = new Info().getClass().getResourceAsStream(resource);
912                            byte[] barr = IOUtil.toBytes(is);
913                            return MD5.getDigestAsString(barr);
914                    }
915                    finally {
916                            IOUtil.closeEL(is);
917                    }
918            }
919    
920            static String createContentFromResource(Resource resource) throws IOException {
921                    return IOUtil.toString(resource, null);
922            }
923    
924            static void createFileFromResourceCheckSizeDiffEL(String resource, Resource file) {
925                    try {
926                            createFileFromResourceCheckSizeDiff(resource, file);
927                    }
928                    catch (Throwable e) {
929                            aprint.err(resource);
930                            aprint.err(file);
931                            e.printStackTrace();
932                    }
933            }
934    
935            /**
936             * creates a File and his content froma a resurce
937             * 
938             * @param resource
939             * @param file
940             * @throws IOException
941             */
942            static void createFileFromResourceCheckSizeDiff(String resource, Resource file) throws IOException {
943                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
944                    IOUtil.copy(new Info().getClass().getResourceAsStream(resource), baos, true, false);
945                    byte[] barr = baos.toByteArray();
946    
947                    if (file.exists()) {
948                            long trgSize = file.length();
949                            long srcSize = barr.length;
950                            if (srcSize == trgSize)
951                                    return;
952    
953                            SystemOut.printDate(SystemUtil.getPrintWriter(SystemUtil.OUT), "update file:" + file);
954                            SystemOut.printDate(SystemUtil.getPrintWriter(SystemUtil.OUT), " - source:" + srcSize);
955                            SystemOut.printDate(SystemUtil.getPrintWriter(SystemUtil.OUT), " - target:" + trgSize);
956    
957                    }
958                    else
959                            file.createNewFile();
960    
961                    // SystemOut.printDate("write file:"+file);
962                    IOUtil.copy(new ByteArrayInputStream(barr), file, true);
963            }
964    
965            /**
966             * Creates all files for Railo Context
967             * 
968             * @param configDir
969             * @throws IOException
970             * @throws IOException
971             */
972            public static void createContextFiles(Resource configDir, ServletConfig servletConfig, boolean doNew) throws IOException {
973                    // NICE dies muss dynamisch ersstelt werden, da hier der admin hinkommt
974                    // und dieser sehr viele files haben wird
975                    Resource contextDir = configDir.getRealResource("context");
976                    if (!contextDir.exists())
977                            contextDir.mkdirs();
978    
979                    // custom locale files
980                    {
981                            Resource dir = configDir.getRealResource("locales");
982                            if (!dir.exists())
983                                    dir.mkdirs();
984                            Resource file = dir.getRealResource("pt-PT-date.df");
985                            if (!file.exists())
986                                    createFileFromResourceEL("/resource/locales/pt-PT-date.df", file);
987                    }
988    
989                    // Jacob
990                    if (SystemUtil.isWindows()) {
991                            Resource systemDir = SystemUtil.getSystemDirectory();
992                            if (systemDir != null) {
993    
994                                    String name = (SystemUtil.getJREArch() == SystemUtil.ARCH_64) ? "jacob-x64.dll" : "jacob-x86.dll";
995    
996                                    Resource jacob = systemDir.getRealResource(name);
997                                    if (!jacob.exists()) {
998                                            createFileFromResourceEL("/resource/bin/" + name, jacob);
999                                    }
1000                                    // SystemOut.printDate(SystemUtil.PRINTWRITER_OUT,"set-property -> "+LibraryLoader.JACOB_DLL_PATH+":"+jacob.getAbsolutePath());
1001                                    System.setProperty(LibraryLoader.JACOB_DLL_PATH, jacob.getAbsolutePath());
1002                                    // SystemOut.printDate(SystemUtil.PRINTWRITER_OUT,"set-property -> "+LibraryLoader.JACOB_DLL_NAME+":"+name);
1003                                    System.setProperty(LibraryLoader.JACOB_DLL_NAME, name);
1004    
1005                                    // jacob.dll.name.x86 & jacob.dll.name.x64
1006    
1007                            }
1008                    }
1009    
1010                    // video
1011                    Resource videoDir = configDir.getRealResource("video");
1012                    if (!videoDir.exists())
1013                            videoDir.mkdirs();
1014    
1015                    Resource video = videoDir.getRealResource("video.xml");
1016                    if (!video.exists())
1017                            createFileFromResourceEL("/resource/video/video.xml", video);
1018    
1019                    // bin
1020                    Resource binDir = configDir.getRealResource("bin");
1021                    if (!binDir.exists())
1022                            binDir.mkdirs();
1023    
1024                    Resource ctDir = configDir.getRealResource("customtags");
1025                    if (!ctDir.exists())
1026                            ctDir.mkdirs();
1027    
1028                    Resource f = binDir.getRealResource("jacob.dll");
1029                    if (!f.exists())
1030                            createFileFromResourceEL("/resource/bin/jacob.dll", f);
1031    
1032                    Resource storDir = configDir.getRealResource("storage");
1033                    if (!storDir.exists())
1034                            storDir.mkdirs();
1035    
1036                    Resource cfcDir = configDir.getRealResource("components");
1037                    if (!cfcDir.exists())
1038                            cfcDir.mkdirs();
1039    
1040                    // remove old cacerts files, they are now only in the server context
1041                    Resource secDir = configDir.getRealResource("security");
1042                    if (secDir.exists()) {
1043                            f = secDir.getRealResource("cacerts");
1044                            if (f.exists())
1045                                    f.delete();
1046                            if (ResourceUtil.isEmpty(secDir))
1047                                    secDir.delete();
1048                    }
1049    
1050                    f = contextDir.getRealResource("railo-context.ra");
1051                    if (!f.exists() || doNew)
1052                            createFileFromResourceEL("/resource/context/railo-context.ra", f);
1053                    else
1054                            createFileFromResourceCheckSizeDiffEL("/resource/context/railo-context.ra", f);
1055    
1056                    f = contextDir.getRealResource("component-dump.cfm");
1057                    if (!f.exists())
1058                            createFileFromResourceEL("/resource/context/component-dump.cfm", f);
1059    
1060                    // Component.cfc
1061                    String badContent = "<cfcomponent displayname=\"Component\" hint=\"This is the Base Component\">\n</cfcomponent>";
1062                    String badVersion = "704b5bd8597be0743b0c99a644b65896";
1063                    f = contextDir.getRealResource("Component.cfc");
1064    
1065                    if (!f.exists())
1066                            createFileFromResourceEL("/resource/context/Component.cfc", f);
1067                    else if (doNew && badVersion.equals(ConfigWebUtil.createMD5FromResource(f))) {
1068                            createFileFromResourceEL("/resource/context/Component.cfc", f);
1069                    }
1070                    else if (doNew && badContent.equals(createContentFromResource(f).trim())) {
1071                            createFileFromResourceEL("/resource/context/Component.cfc", f);
1072                    }
1073    
1074                    f = contextDir.getRealResource(Constants.APP_CFM);
1075                    if (!f.exists())
1076                            createFileFromResourceEL("/resource/context/application.cfm", f);
1077    
1078                    f = contextDir.getRealResource("form.cfm");
1079                    if (!f.exists() || doNew)
1080                            createFileFromResourceEL("/resource/context/form.cfm", f);
1081    
1082                    f = contextDir.getRealResource("graph.cfm");
1083                    if (!f.exists() || doNew)
1084                            createFileFromResourceEL("/resource/context/graph.cfm", f);
1085    
1086                    f = contextDir.getRealResource("wddx.cfm");
1087                    if (!f.exists())
1088                            createFileFromResourceEL("/resource/context/wddx.cfm", f);
1089    
1090                    f = contextDir.getRealResource("railo-applet.cfm");
1091                    if (!f.exists())
1092                            createFileFromResourceEL("/resource/context/railo-applet.cfm", f);
1093    
1094                    f = contextDir.getRealResource("railo-applet.jar");
1095                    if (!f.exists() || doNew)
1096                            createFileFromResourceEL("/resource/context/railo-applet.jar", f);
1097    
1098                    // f=new BinaryFile(contextDir,"railo_context.ra");
1099                    // if(!f.exists())createFileFromResource("/resource/context/railo_context.ra",f);
1100    
1101                    f = contextDir.getRealResource("admin.cfm");
1102                    if (!f.exists())
1103                            createFileFromResourceEL("/resource/context/admin.cfm", f);
1104    
1105                    // Video
1106                    f = contextDir.getRealResource("swfobject.js");
1107                    if (!f.exists() || doNew)
1108                            createFileFromResourceEL("/resource/video/swfobject.js", f);
1109                    f = contextDir.getRealResource("swfobject.js.cfm");
1110                    if (!f.exists() || doNew)
1111                            createFileFromResourceEL("/resource/video/swfobject.js.cfm", f);
1112    
1113                    f = contextDir.getRealResource("mediaplayer.swf");
1114                    if (!f.exists() || doNew)
1115                            createFileFromResourceEL("/resource/video/mediaplayer.swf", f);
1116                    f = contextDir.getRealResource("mediaplayer.swf.cfm");
1117                    if (!f.exists() || doNew)
1118                            createFileFromResourceEL("/resource/video/mediaplayer.swf.cfm", f);
1119    
1120                    Resource adminDir = contextDir.getRealResource("admin");
1121                    if (!adminDir.exists())
1122                            adminDir.mkdirs();
1123    
1124                    // Plugin
1125                    Resource pluginDir = adminDir.getRealResource("plugin");
1126                    if (!pluginDir.exists())
1127                            pluginDir.mkdirs();
1128    
1129                    f = pluginDir.getRealResource("Plugin.cfc");
1130                    if (!f.exists())
1131                            createFileFromResourceEL("/resource/context/admin/plugin/Plugin.cfc", f);
1132    
1133                    // Plugin DDNS
1134                    /*
1135                     * File ddns = new File(pluginDir,"DDNS");
1136                     * if(!ddns.exists())ddns.mkdirs();
1137                     * 
1138                     * f=new File(ddns,"language.xml");
1139                     * if(!f.exists())createFileFromResource
1140                     * ("/resource/context/admin/plugin/DDNS/language.xml",f);
1141                     * 
1142                     * f=new File(ddns,"overview.cfm");
1143                     * if(!f.exists())createFileFromResource
1144                     * ("/resource/context/admin/plugin/DDNS/overview.cfm",f);
1145                     * 
1146                     * f=new File(ddns,"Action.cfc"); if(!f.exists())createFileFromResource(
1147                     * "/resource/context/admin/plugin/DDNS/Action.cfc",f);
1148                     */
1149    
1150                    // Plugin Simon
1151                    Resource simon = pluginDir.getRealResource("Simon");
1152                    if (!simon.exists())
1153                            simon.mkdirs();
1154    
1155                    f = simon.getRealResource("language.xml");
1156                    if (!f.exists())
1157                            createFileFromResourceEL("/resource/context/admin/plugin/Simon/language.xml", f);
1158    
1159                    f = simon.getRealResource("overview.cfm");
1160                    if (!f.exists())
1161                            createFileFromResourceEL("/resource/context/admin/plugin/Simon/overview.cfm", f);
1162    
1163                    f = simon.getRealResource("simon.swf.cfm");
1164                    if (!f.exists())
1165                            createFileFromResourceEL("/resource/context/admin/plugin/Simon/simon.swf.cfm", f);
1166    
1167                    f = simon.getRealResource("Action.cfc");
1168                    if (!f.exists())
1169                            createFileFromResourceEL("/resource/context/admin/plugin/Simon/Action.cfc", f);
1170    
1171                    // Plugin Note
1172                    Resource note = pluginDir.getRealResource("Note");
1173                    if (!note.exists())
1174                            note.mkdirs();
1175    
1176                    f = note.getRealResource("language.xml");
1177                    if (!f.exists())
1178                            createFileFromResourceEL("/resource/context/admin/plugin/Note/language.xml", f);
1179    
1180                    f = note.getRealResource("overview.cfm");
1181                    if (!f.exists())
1182                            createFileFromResourceEL("/resource/context/admin/plugin/Note/overview.cfm", f);
1183    
1184                    f = note.getRealResource("Action.cfc");
1185                    if (!f.exists())
1186                            createFileFromResourceEL("/resource/context/admin/plugin/Note/Action.cfc", f);
1187    
1188                    // gateway
1189                    Resource gatewayDir = configDir.getRealResource("components");
1190                    if (!gatewayDir.exists())
1191                            gatewayDir.mkdirs();
1192    
1193                    Resource dir = gatewayDir.getRealResource("railo/extension/gateway/");
1194                    if (!dir.exists())
1195                            dir.mkdirs();
1196    
1197                    f = dir.getRealResource("DummyGateway.cfc");
1198                    if (!f.exists() || doNew)
1199                            createFileFromResourceEL("/resource/context/gateway/DummyGateway.cfc", f);
1200    
1201                    f = dir.getRealResource("DirectoryWatcher.cfc");
1202                    if (!f.exists() || doNew)
1203                            createFileFromResourceEL("/resource/context/gateway/DirectoryWatcher.cfc", f);
1204    
1205                    f = dir.getRealResource("DirectoryWatcherListener.cfc");
1206                    if (!f.exists() || doNew)
1207                            createFileFromResourceEL("/resource/context/gateway/DirectoryWatcherListener.cfc", f);
1208    
1209                    f = dir.getRealResource("MailWatcher.cfc");
1210                    if (!f.exists() || doNew)
1211                            createFileFromResourceEL("/resource/context/gateway/MailWatcher.cfc", f);
1212    
1213                    f = dir.getRealResource("MailWatcherListener.cfc");
1214                    if (!f.exists() || doNew)
1215                            createFileFromResourceEL("/resource/context/gateway/MailWatcherListener.cfc", f);
1216    
1217                    // resources/language
1218                    Resource langDir = adminDir.getRealResource("resources/language");
1219                    langDir.mkdirs();
1220                    f = langDir.getRealResource("en.xml");
1221                    if (!f.exists() || doNew)
1222                            createFileFromResourceEL("/resource/context/admin/resources/language/en.xml", f);
1223    
1224                    f = langDir.getRealResource("de.xml");
1225                    if (!f.exists() || doNew)
1226                            createFileFromResourceEL("/resource/context/admin/resources/language/de.xml", f);
1227    
1228                    // G DRIVER
1229                    Resource gDir = adminDir.getRealResource("gdriver");
1230                    if (!gDir.exists())
1231                            gDir.mkdirs();
1232    
1233                    f = gDir.getRealResource("Gateway.cfc");
1234                    if (!f.exists() || doNew)
1235                            createFileFromResourceEL("/resource/context/admin/gdriver/Gateway.cfc", f);
1236    
1237                    f = gDir.getRealResource("DirectoryWatcher.cfc");
1238                    if (!f.exists() || doNew)
1239                            createFileFromResourceEL("/resource/context/admin/gdriver/DirectoryWatcher.cfc", f);
1240    
1241                    f = gDir.getRealResource("MailWatcher.cfc");
1242                    if (!f.exists() || doNew)
1243                            createFileFromResourceEL("/resource/context/admin/gdriver/MailWatcher.cfc", f);
1244    
1245                    f = gDir.getRealResource("Field.cfc");
1246                    if (!f.exists() || doNew)
1247                            createFileFromResourceEL("/resource/context/admin/gdriver/Field.cfc", f);
1248    
1249                    f = gDir.getRealResource("Group.cfc");
1250                    if (!f.exists() || doNew)
1251                            createFileFromResourceEL("/resource/context/admin/gdriver/Group.cfc", f);
1252    
1253                    // DEBUG
1254                    Resource debug = adminDir.getRealResource("debug");
1255                    if (!debug.exists())
1256                            debug.mkdirs();
1257    
1258                    f = debug.getRealResource("Debug.cfc");
1259                    if (!f.exists() || doNew)
1260                            createFileFromResourceEL("/resource/context/admin/debug/Debug.cfc", f);
1261    
1262                    f = debug.getRealResource("Field.cfc");
1263                    if (!f.exists() || doNew)
1264                            createFileFromResourceEL("/resource/context/admin/debug/Field.cfc", f);
1265    
1266                    f = debug.getRealResource("Group.cfc");
1267                    if (!f.exists() || doNew)
1268                            createFileFromResourceEL("/resource/context/admin/debug/Group.cfc", f);
1269    
1270                    f = debug.getRealResource("Classic.cfc");
1271                    if (!f.exists() || doNew)
1272                            createFileFromResourceEL("/resource/context/admin/debug/Classic.cfc", f);
1273    
1274                    f = debug.getRealResource("Modern.cfc");
1275                    if (!f.exists() || doNew)
1276                            createFileFromResourceEL("/resource/context/admin/debug/Modern.cfc", f);
1277    
1278                    f = debug.getRealResource("Comment.cfc");
1279                    if (!f.exists() || doNew)
1280                            createFileFromResourceEL("/resource/context/admin/debug/Comment.cfc", f);
1281    
1282                    // C DRIVER
1283                    Resource cDir = adminDir.getRealResource("cdriver");
1284                    if (!cDir.exists())
1285                            cDir.mkdirs();
1286    
1287                    f = cDir.getRealResource("Cache.cfc");
1288                    if (!f.exists() || doNew)
1289                            createFileFromResourceEL("/resource/context/admin/cdriver/Cache.cfc", f);
1290    
1291                    f = cDir.getRealResource("RamCache.cfc");
1292                    if (!f.exists() || doNew)
1293                            createFileFromResourceEL("/resource/context/admin/cdriver/RamCache.cfc", f);
1294    
1295                    f = cDir.getRealResource("EHCacheLite.cfc");
1296                    if (!f.exists() || doNew)
1297                            createFileFromResourceEL("/resource/context/admin/cdriver/EHCacheLite.cfc", f);
1298    
1299                    f = cDir.getRealResource("Field.cfc");
1300                    if (!f.exists() || doNew)
1301                            createFileFromResourceEL("/resource/context/admin/cdriver/Field.cfc", f);
1302    
1303                    f = cDir.getRealResource("Group.cfc");
1304                    if (!f.exists() || doNew)
1305                            createFileFromResourceEL("/resource/context/admin/cdriver/Group.cfc", f);
1306    
1307                    // DB DRIVER
1308                    Resource dbDir = adminDir.getRealResource("dbdriver");
1309                    if (!dbDir.exists())
1310                            dbDir.mkdirs();
1311    
1312                    f = dbDir.getRealResource("Driver.cfc");
1313                    if (!f.exists() || doNew)
1314                            createFileFromResourceEL("/resource/context/admin/dbdriver/Driver.cfc", f);
1315    
1316                    f = dbDir.getRealResource("HSQLDB.cfc");
1317                    if (!f.exists() || doNew)
1318                            createFileFromResourceEL("/resource/context/admin/dbdriver/HSQLDB.cfc", f);
1319    
1320                    f = dbDir.getRealResource("H2.cfc");
1321                    if (!f.exists() || doNew)
1322                            createFileFromResourceEL("/resource/context/admin/dbdriver/H2.cfc", f);
1323    
1324                    f = dbDir.getRealResource("MSSQL.cfc");
1325                    if (!f.exists() || doNew)
1326                            createFileFromResourceEL("/resource/context/admin/dbdriver/MSSQL.cfc", f);
1327    
1328                    f = dbDir.getRealResource("MSSQL2.cfc");
1329                    if (!f.exists() || doNew)
1330                            createFileFromResourceEL("/resource/context/admin/dbdriver/MSSQL2.cfc", f);
1331    
1332                    f = dbDir.getRealResource("DB2.cfc");
1333                    if (!f.exists() || doNew)
1334                            createFileFromResourceEL("/resource/context/admin/dbdriver/DB2.cfc", f);
1335    
1336                    f = dbDir.getRealResource("Oracle.cfc");
1337                    if (!f.exists() || doNew)
1338                            createFileFromResourceEL("/resource/context/admin/dbdriver/Oracle.cfc", f);
1339    
1340                    f = dbDir.getRealResource("MySQL.cfc");
1341                    if (!f.exists() || doNew)
1342                            createFileFromResourceEL("/resource/context/admin/dbdriver/MySQL.cfc", f);
1343    
1344                    f = dbDir.getRealResource("ODBC.cfc");
1345                    if (!f.exists() || doNew)
1346                            createFileFromResourceEL("/resource/context/admin/dbdriver/ODBC.cfc", f);
1347    
1348                    f = dbDir.getRealResource("Sybase.cfc");
1349                    if (!f.exists() || doNew)
1350                            createFileFromResourceEL("/resource/context/admin/dbdriver/Sybase.cfc", f);
1351    
1352                    f = dbDir.getRealResource("PostgreSql.cfc");
1353                    if (!f.exists() || doNew)
1354                            createFileFromResourceEL("/resource/context/admin/dbdriver/PostgreSql.cfc", f);
1355    
1356                    f = dbDir.getRealResource("Other.cfc");
1357                    if (!f.exists() || doNew)
1358                            createFileFromResourceEL("/resource/context/admin/dbdriver/Other.cfc", f);
1359    
1360                    f = dbDir.getRealResource("Firebird.cfc");
1361                    if (!f.exists() || doNew)
1362                            createFileFromResourceEL("/resource/context/admin/dbdriver/Firebird.cfc", f);
1363    
1364                    Resource typesDir = dbDir.getRealResource("types");
1365                    if (!typesDir.exists())
1366                            typesDir.mkdirs();
1367    
1368                    f = typesDir.getRealResource("Field.cfc");
1369                    if (!f.exists() || doNew)
1370                            createFileFromResourceEL("/resource/context/admin/dbdriver/types/Field.cfc", f);
1371    
1372                    Resource templatesDir = contextDir.getRealResource("templates");
1373                    if (!templatesDir.exists())
1374                            templatesDir.mkdirs();
1375    
1376                    Resource errorDir = templatesDir.getRealResource("error");
1377                    if (!errorDir.exists())
1378                            errorDir.mkdirs();
1379    
1380                    f = errorDir.getRealResource("error.cfm");
1381                    if (!f.exists() || doNew)
1382                            createFileFromResourceEL("/resource/context/templates/error/error.cfm", f);
1383    
1384                    f = errorDir.getRealResource("error-neo.cfm");
1385                    if (!f.exists() || doNew)
1386                            createFileFromResourceEL("/resource/context/templates/error/error-neo.cfm", f);
1387    
1388                    f = errorDir.getRealResource("error-public.cfm");
1389                    if (!f.exists() || doNew)
1390                            createFileFromResourceEL("/resource/context/templates/error/error-public.cfm", f);
1391    
1392                    Resource displayDir = templatesDir.getRealResource("display");
1393                    if (!displayDir.exists())
1394                            displayDir.mkdirs();
1395    
1396                    f = displayDir.getRealResource(Constants.APP_CFM);
1397                    if (!f.exists() || doNew)
1398                            createFileFromResourceEL("/resource/context/templates/display/Application.cfm", f);
1399    
1400                    f = displayDir.getRealResource(Constants.APP_CFC);
1401                    if (!f.exists() || doNew)
1402                            createFileFromResourceEL("/resource/context/templates/display/Application.cfc", f);
1403    
1404                    Resource lib = ResourceUtil.toResource(CFMLEngineFactory.getClassLoaderRoot(TP.class.getClassLoader()));
1405                    f = lib.getRealResource("jfreechart-patch.jar");
1406                    if (!f.exists())
1407                            createFileFromResourceEL("/resource/lib/jfreechart-patch.jar", f);
1408    
1409            }
1410    
1411            public static void createContextFilesPost(Resource configDir, ConfigImpl config, ServletConfig servletConfig, boolean isEventGatewayContext, boolean doNew) {
1412                    Resource contextDir = configDir.getRealResource("context");
1413                    if (!contextDir.exists())
1414                            contextDir.mkdirs();
1415    
1416                    Resource adminDir = contextDir.getRealResource("admin");
1417                    if (!adminDir.exists())
1418                            adminDir.mkdirs();
1419    
1420                    // Plugin
1421                    Resource pluginDir = adminDir.getRealResource("plugin");
1422                    if (!pluginDir.exists())
1423                            pluginDir.mkdirs();
1424    
1425                    // deploy org.railo.cfml components
1426                    if (config instanceof ConfigWeb) {
1427                            ImportDefintion _import = config.getComponentDefaultImport();
1428                            String path = _import.getPackageAsPath();
1429                            Resource components = config.getConfigDir().getRealResource("components");
1430                            Resource dir = components.getRealResource(path);
1431                            dir.mkdirs();
1432                            // print.o(dir);
1433                            ComponentFactory.deploy(dir, doNew);
1434                    }
1435    
1436                    // flex
1437                    if (!isEventGatewayContext && servletConfig != null && config.getAMFConfigType() == ConfigImpl.AMF_CONFIG_TYPE_XML) {
1438                            String strPath = servletConfig.getServletContext().getRealPath("/WEB-INF");
1439                            Resource webInf = ResourcesImpl.getFileResourceProvider().getResource(strPath);
1440    
1441                            Resource flex = webInf.getRealResource("flex");
1442                            if (!flex.exists())
1443                                    flex.mkdirs();
1444    
1445                            Resource f = flex.getRealResource("messaging-config.xml");
1446                            if (!f.exists() || doNew)
1447                                    createFileFromResourceEL("/resource/flex/messaging-config.xml", f);
1448                            f = flex.getRealResource("proxy-config.xml");
1449                            if (!f.exists() || doNew)
1450                                    createFileFromResourceEL("/resource/flex/proxy-config.xml", f);
1451                            f = flex.getRealResource("remoting-config.xml");
1452                            if (!f.exists() || doNew)
1453                                    createFileFromResourceEL("/resource/flex/remoting-config.xml", f);
1454                            f = flex.getRealResource("services-config.xml");
1455                            if (!f.exists() || doNew)
1456                                    createFileFromResourceEL("/resource/flex/services-config.xml", f);
1457    
1458                    }
1459    
1460            }
1461    
1462            static boolean doNew(Resource contextDir) {
1463    
1464                    final boolean readonly = false;
1465                    try {
1466                            Resource version = contextDir.getRealResource("version");
1467                            String v = Info.getVersionAsString() + "-" + Info.getStateAsString() + "-" + Info.getRealeaseTime();
1468                            if (!version.exists()) {
1469                                    if (!readonly) {
1470                                            version.createNewFile();
1471                                            IOUtil.write(version, v, SystemUtil.getCharset(), false);
1472                                    }
1473                                    return true;
1474                            }
1475                            else if (!IOUtil.toString(version, SystemUtil.getCharset()).equals(v)) {
1476                                    if (!readonly)
1477                                            IOUtil.write(version, v, SystemUtil.getCharset(), false);
1478    
1479                                    return true;
1480                            }
1481                    }
1482                    catch (Throwable t) {
1483                    }
1484                    return false;
1485            }
1486    
1487            private static void doCheckChangesInLibraries(ConfigImpl config) {
1488                    // create current hash from libs
1489                    TagLib[] tlds = config.getTLDs();
1490                    FunctionLib[] flds = config.getFLDs();
1491    
1492                    // charset
1493                    StringBuffer sb = new StringBuffer(config.getTemplateCharset());
1494                    sb.append(';');
1495    
1496                    // dot notation upper case
1497                    sb.append(config.getDotNotationUpperCase());
1498                    sb.append(';');
1499    
1500                    // supress ws before arg
1501                    sb.append(config.getSupressWSBeforeArg());
1502                    sb.append(';');
1503    
1504                    // full null support
1505                    sb.append(config.getFullNullSupport());
1506                    sb.append(';');
1507    
1508                    // tld
1509                    for (int i = 0; i < tlds.length; i++) {
1510                            sb.append(tlds[i].getHash());
1511                    }
1512    
1513                    // fld
1514                    for (int i = 0; i < flds.length; i++) {
1515                            sb.append(flds[i].getHash());
1516                    }
1517    
1518                    boolean hasChanged = false;
1519                    try {
1520                            String hashValue = Md5.getDigestAsString(sb.toString());
1521    
1522                            // check and compare lib version file
1523                            Resource contextDir = config.getConfigDir();
1524                            Resource libHash = contextDir.getRealResource("lib-hash");
1525    
1526                            if (!libHash.exists()) {
1527                                    libHash.createNewFile();
1528                                    IOUtil.write(libHash, hashValue, SystemUtil.getCharset(), false);
1529    
1530                                    hasChanged = true;
1531                            }
1532                            else if (!IOUtil.toString(libHash, SystemUtil.getCharset()).equals(hashValue)) {
1533                                    IOUtil.write(libHash, hashValue, SystemUtil.getCharset(), false);
1534                                    hasChanged = true;
1535                            }
1536                    }
1537                    catch (IOException e) {
1538                    }
1539                    // chnage Compile type
1540                    if (hasChanged) {
1541                            try {
1542                                    config.getDeployDirectory().remove(true);
1543                            }
1544                            catch (IOException e) {
1545                                    e.printStackTrace(config.getErrWriter());
1546                            }
1547                    }
1548    
1549            }
1550    
1551            /**
1552             * load mapings from XML Document
1553             * 
1554             * @param configServer
1555             * @param config
1556             * @param doc
1557             * @throws IOException
1558             */
1559            private static void loadMappings(ConfigServerImpl configServer, ConfigImpl config, Document doc, int mode) throws IOException {
1560                    boolean hasAccess = ConfigWebUtil.hasAccess(config, SecurityManager.TYPE_MAPPING);
1561                    Element el = getChildByName(doc.getDocumentElement(), "mappings");
1562    
1563                    String strLogger = el.getAttribute("log");
1564                    int logLevel = LogUtil.toIntType(el.getAttribute("log-level"), Log.LEVEL_ERROR);
1565                    if (StringUtil.isEmpty(strLogger)) {
1566                            if (configServer != null) {
1567                                    LogAndSource log = configServer.getMailLogger();
1568                                    strLogger = log.getSource();
1569                                    logLevel = log.getLogLevel();
1570                            }
1571                            else
1572                                    strLogger = "{railo-config}/logs/mapping.log";
1573                    }
1574    
1575                    config.setMappingLogger(ConfigWebUtil.getLogAndSource(configServer, config, strLogger, true, logLevel));
1576    
1577                    Element[] _mappings = getChildren(el, "mapping");
1578    
1579                    HashTable mappings = new HashTable();
1580                    Mapping tmp;
1581    
1582                    if (configServer != null && config instanceof ConfigWeb) {
1583                            Mapping[] sm = configServer.getMappings();
1584                            for (int i = 0; i < sm.length; i++) {
1585    
1586                                    if (!sm[i].isHidden()) {
1587                                            if (sm[i] instanceof MappingImpl) {
1588                                                    tmp = ((MappingImpl) sm[i]).cloneReadOnly(config);
1589                                                    mappings.put(tmp.getVirtualLowerCase(), tmp);
1590    
1591                                            }
1592                                            else {
1593                                                    tmp = sm[i];
1594                                                    mappings.put(tmp.getVirtualLowerCase(), tmp);
1595                                            }
1596                                    }
1597                            }
1598                    }
1599    
1600                    boolean finished = false;
1601    
1602                    if (hasAccess) {
1603                            for (int i = 0; i < _mappings.length; i++) {
1604                                    el = _mappings[i];
1605    
1606                                    // File
1607                                    // physical=getDir(sc,el.getAttribute("physical"),null,configDir);
1608                                    // File
1609                                    // archive=getFile(sc,el.getAttribute("archive"),null,configDir);
1610    
1611                                    String physical = el.getAttribute("physical");
1612                                    String archive = el.getAttribute("archive");
1613                                    String virtual = el.getAttribute("virtual");
1614                                    String listType = el.getAttribute("listener-type");
1615                                    String listMode = el.getAttribute("listener-mode");
1616                                    boolean readonly = toBoolean(el.getAttribute("readonly"), false);
1617                                    boolean hidden = toBoolean(el.getAttribute("hidden"), false);
1618                                    boolean toplevel = toBoolean(el.getAttribute("toplevel"), true);
1619                                    int clMaxEl = toInt(el.getAttribute("classloader-max-elements"), 100);
1620    
1621                                    if (virtual.equalsIgnoreCase("/railo-context/")) {
1622                                            if (StringUtil.isEmpty(listType, true))
1623                                                    listType = "modern";
1624                                            if (StringUtil.isEmpty(listMode, true))
1625                                                    listMode = "curr2root";
1626                                            toplevel = true;
1627                                    }
1628    
1629                                    ApplicationListener listener = ConfigWebUtil.loadListener(listType, null);
1630                                    int listenerMode = ConfigWebUtil.toListenerMode(listMode, -1);
1631                                    if (listener != null || listenerMode != -1) {
1632                                            // type
1633                                            if (mode == ConfigImpl.MODE_STRICT)
1634                                                    listener = new ModernAppListener();
1635                                            else if (listener == null)
1636                                                    listener = ConfigWebUtil.loadListener(config.getApplicationListener().getType(), null);
1637                                            if (listener == null)// this should never be true
1638                                                    listener = new ModernAppListener();
1639    
1640                                            // mode
1641                                            if (listenerMode == -1) {
1642                                                    listenerMode = config.getApplicationListener().getMode();
1643                                            }
1644                                            listener.setMode(listenerMode);
1645    
1646                                    }
1647    
1648                                    // physical!=null &&
1649                                    if ((physical != null || archive != null)) {
1650                                            
1651                                            short insTemp=inspectTemplate(el);
1652                                            
1653                                            //boolean trusted = toBoolean(el.getAttribute("trusted"), false);
1654                                            
1655                                            
1656                                            String primary = el.getAttribute("primary");
1657                                            boolean physicalFirst = primary == null || !primary.equalsIgnoreCase("archive");
1658    
1659                                            tmp = new MappingImpl(config, virtual, physical, archive, insTemp, physicalFirst, hidden, readonly, toplevel, false, false, listener, clMaxEl);
1660                                            mappings.put(tmp.getVirtualLowerCase(), tmp);
1661                                            if (virtual.equals("/")) {
1662                                                    finished = true;
1663                                                    // break;
1664                                            }
1665                                    }
1666                            }
1667                    }
1668    
1669                    if (!finished) {
1670                            tmp = new MappingImpl(config, "/", "/", null, ConfigImpl.INSPECT_UNDEFINED, true, true, true, true, false, false, null);
1671                            mappings.put(tmp.getVirtualLowerCase(), tmp);
1672                    }
1673    
1674                    Mapping[] arrMapping = new Mapping[mappings.size()];
1675                    int index = 0;
1676                    Iterator it = mappings.keySet().iterator();
1677                    while (it.hasNext()) {
1678                            arrMapping[index++] = (Mapping) mappings.get(it.next());
1679                    }
1680                    config.setMappings(arrMapping);
1681                    // config.setMappings((Mapping[]) mappings.toArray(new
1682                    // Mapping[mappings.size()]));
1683            }
1684    
1685            private static short inspectTemplate(Element el) {
1686                    String strInsTemp = el.getAttribute("inspect-template");
1687                    if(StringUtil.isEmpty(strInsTemp)) strInsTemp = el.getAttribute("inspect");
1688                    if(StringUtil.isEmpty(strInsTemp)) {
1689                            Boolean trusted=Caster.toBoolean(el.getAttribute("trusted"),null);
1690                            if(trusted!=null) {
1691                                    if(trusted.booleanValue()) return ConfigImpl.INSPECT_NEVER;
1692                                    return ConfigImpl.INSPECT_ALWAYS;
1693                            }
1694                            return ConfigImpl.INSPECT_UNDEFINED;
1695                    }
1696                    return ConfigWebUtil.inspectTemplate(strInsTemp,ConfigImpl.INSPECT_UNDEFINED);  
1697            }
1698    
1699            private static void loadRest(ConfigServerImpl configServer, ConfigImpl config, Document doc) throws IOException {
1700                    boolean hasAccess = true;// MUST
1701                                                                            // ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_REST);
1702                    boolean hasCS = configServer != null;
1703                    Element el = getChildByName(doc.getDocumentElement(), "rest");
1704    
1705                    // Log
1706                    String strLogger = el.getAttribute("log");
1707                    int logLevel = LogUtil.toIntType(el.getAttribute("log-level"), Log.LEVEL_ERROR);
1708                    if (StringUtil.isEmpty(strLogger)) {
1709                            if (configServer != null) {
1710                                    LogAndSource log = configServer.getRestLogger();
1711                                    strLogger = log.getSource();
1712                                    logLevel = log.getLogLevel();
1713                            }
1714                            else
1715                                    strLogger = "{railo-config}/logs/rest.log";
1716                    }
1717                    config.setRestLogger(ConfigWebUtil.getLogAndSource(configServer, config, strLogger, true, logLevel));
1718    
1719                    // allow-changes
1720                    /*
1721                     * Boolean
1722                     * allowChanges=Caster.toBoolean(el.getAttribute("allow-changes"),null);
1723                     * if(allowChanges!=null){
1724                     * config.setRestAllowChanges(allowChanges.booleanValue()); } else
1725                     * if(hasCS){
1726                     * config.setRestAllowChanges(configServer.getRestAllowChanges()); }
1727                     */
1728    
1729                    // list
1730                    Boolean list = Caster.toBoolean(el.getAttribute("list"), null);
1731                    if (list != null) {
1732                            config.setRestList(list.booleanValue());
1733                    }
1734                    else if (hasCS) {
1735                            config.setRestList(configServer.getRestList());
1736                    }
1737    
1738                    Element[] _mappings = getChildren(el, "mapping");
1739    
1740                    // first get mapping defined in server admin (read-only)
1741                    Map<String, railo.runtime.rest.Mapping> mappings = new HashMap<String, railo.runtime.rest.Mapping>();
1742                    railo.runtime.rest.Mapping tmp;
1743                    if (configServer != null && config instanceof ConfigWeb) {
1744                            railo.runtime.rest.Mapping[] sm = configServer.getRestMappings();
1745                            for (int i = 0; i < sm.length; i++) {
1746    
1747                                    if (!sm[i].isHidden()) {
1748                                            tmp = sm[i].duplicate(config, Boolean.TRUE);
1749                                            mappings.put(tmp.getVirtual(), tmp);
1750                                    }
1751                            }
1752                    }
1753    
1754                    // get current mappings
1755                    if (hasAccess) {
1756                            for (int i = 0; i < _mappings.length; i++) {
1757                                    el = _mappings[i];
1758                                    String physical = el.getAttribute("physical");
1759                                    String virtual = el.getAttribute("virtual");
1760                                    boolean readonly = toBoolean(el.getAttribute("readonly"), false);
1761                                    boolean hidden = toBoolean(el.getAttribute("hidden"), false);
1762                                    boolean _default = toBoolean(el.getAttribute("default"), false);
1763                                    if (physical != null) {
1764                                            tmp = new railo.runtime.rest.Mapping(config, virtual, physical, hidden, readonly, _default);
1765                                            mappings.put(tmp.getVirtual(), tmp);
1766                                    }
1767                            }
1768                    }
1769    
1770                    config.setRestMappings(mappings.values().toArray(new railo.runtime.rest.Mapping[mappings.size()]));
1771            }
1772    
1773            private static void loadFlex(ConfigServerImpl configServer, ConfigImpl config, Document doc) {
1774    
1775                    Element el = getChildByName(doc.getDocumentElement(), "flex");
1776                    if (configServer != null)
1777                            ;
1778    
1779                    // deploy
1780                    String strConfig = el.getAttribute("configuration");
1781                    if (!StringUtil.isEmpty(strConfig))
1782                            config.setAMFConfigType(strConfig);
1783                    else if (configServer != null)
1784                            config.setAMFConfigType(configServer.getAMFConfigType());
1785    
1786                    // caster
1787                    String strCaster = el.getAttribute("caster");
1788                    if (StringUtil.isEmpty(strCaster))
1789                            strCaster = el.getAttribute("caster-class");
1790    
1791                    // arguments
1792                    String strArgs = el.getAttribute("caster-arguments");
1793                    if (StringUtil.isEmpty(strArgs))
1794                            strArgs = el.getAttribute("caster-class-arguments");
1795                    toArguments(strArgs, false);
1796    
1797                    if (!StringUtil.isEmpty(strCaster))
1798                            config.setAMFCaster(strCaster, toArguments(strArgs, false));
1799                    else if (configServer != null)
1800                            config.setAMFCaster(config.getAMFCasterClass(), config.getAMFCasterArguments());
1801    
1802            }
1803    
1804            private static void loadExeLog(ConfigServerImpl configServer, ConfigImpl config, Document doc) {
1805    
1806                    boolean hasServer = configServer != null;
1807    
1808                    Element el = getChildByName(doc.getDocumentElement(), "execution-log");
1809    
1810                    // enabled
1811                    Boolean bEnabled = Caster.toBoolean(el.getAttribute("enabled"), null);
1812                    if (bEnabled == null) {
1813                            if (hasServer)
1814                                    config.setExecutionLogEnabled(configServer.getExecutionLogEnabled());
1815                    }
1816                    else
1817                            config.setExecutionLogEnabled(bEnabled.booleanValue());
1818    
1819                    boolean hasChanged = false;
1820                    String val = Caster.toString(config.getExecutionLogEnabled());
1821                    try {
1822                            Resource contextDir = config.getConfigDir();
1823                            Resource exeLog = contextDir.getRealResource("exe-log");
1824    
1825                            if (!exeLog.exists()) {
1826                                    exeLog.createNewFile();
1827                                    IOUtil.write(exeLog, val, SystemUtil.getCharset(), false);
1828                                    hasChanged = true;
1829                            }
1830                            else if (!IOUtil.toString(exeLog, SystemUtil.getCharset()).equals(val)) {
1831                                    IOUtil.write(exeLog, val, SystemUtil.getCharset(), false);
1832                                    hasChanged = true;
1833                            }
1834                    }
1835                    catch (IOException e) {
1836                            e.printStackTrace(config.getErrWriter());
1837                    }
1838    
1839                    if (hasChanged) {
1840                            try {
1841                                    if (config.getDeployDirectory().exists())
1842                                            config.getDeployDirectory().remove(true);
1843                            }
1844                            catch (IOException e) {
1845                                    e.printStackTrace(config.getErrWriter());
1846                            }
1847                    }
1848    
1849                    // class
1850                    String strClass = el.getAttribute("class");
1851                    Class clazz;
1852                    if (!StringUtil.isEmpty(strClass)) {
1853                            try {
1854                                    if ("console".equalsIgnoreCase(strClass))
1855                                            clazz = ConsoleExecutionLog.class;
1856                                    else {
1857                                            Class c = ClassUtil.loadClass(strClass);
1858                                            if ((c.newInstance() instanceof ExecutionLog)) {
1859                                                    clazz = c;
1860                                            }
1861                                            else {
1862                                                    clazz = ConsoleExecutionLog.class;
1863                                                    SystemOut.printDate(config.getErrWriter(), "class [" + strClass + "] must implement the interface " + ExecutionLog.class.getName());
1864                                            }
1865                                    }
1866                            }
1867                            catch (Throwable e) {
1868                                    e.printStackTrace();
1869                                    clazz = ConsoleExecutionLog.class;
1870                            }
1871                            if (clazz != null)
1872                                    SystemOut.printDate(config.getOutWriter(), "loaded ExecutionLog class " + clazz.getName());
1873    
1874                            // arguments
1875                            String strArgs = el.getAttribute("arguments");
1876                            if (StringUtil.isEmpty(strArgs))
1877                                    strArgs = el.getAttribute("class-arguments");
1878                            Map<String, String> args = toArguments(strArgs, true);
1879    
1880                            config.setExecutionLogFactory(new ExecutionLogFactory(clazz, args));
1881                    }
1882                    else {
1883                            if (hasServer)
1884                                    config.setExecutionLogFactory(configServer.getExecutionLogFactory());
1885                            else
1886                                    config.setExecutionLogFactory(new ExecutionLogFactory(ConsoleExecutionLog.class, new HashMap<String, String>()));
1887                    }
1888            }
1889    
1890            /**
1891             * loads and sets the Page Pool
1892             * 
1893             * @param configServer
1894             * @param config
1895             * @param doc
1896             */
1897            private static void loadPagePool(ConfigServer configServer, Config config, Document doc) {
1898                    // TODO xml configuration fr das erstellen
1899                    // config.setPagePool( new PagePool(10000,1000));
1900            }
1901    
1902            /**
1903             * loads datasource settings from XMl DOM
1904             * 
1905             * @param configServer
1906             * @param config
1907             * @param doc
1908             * @throws ClassNotFoundException
1909             */
1910            private static void loadDataSources(ConfigServerImpl configServer, ConfigImpl config, Document doc) throws ClassException {
1911    
1912                    // When set to true, makes JDBC use a representation for DATE data that
1913                    // is compatible with the Oracle8i database.
1914                    System.setProperty("oracle.jdbc.V8Compatible", "true");
1915    
1916                    boolean hasCS = configServer != null;
1917                    Map<String, DataSource> datasources = new HashMap<String, DataSource>();
1918    
1919                    // Copy Parent datasources as readOnly
1920                    if (hasCS) {
1921                            Map<String, DataSource> ds = configServer.getDataSourcesAsMap();
1922                            Iterator<Entry<String, DataSource>> it = ds.entrySet().iterator();
1923                            Entry<String, DataSource> entry;
1924                            while (it.hasNext()) {
1925                                    entry = it.next();
1926                                    if (!entry.getKey().equals("_queryofquerydb"))
1927                                            datasources.put(entry.getKey(), entry.getValue().cloneReadOnly());
1928                            }
1929                    }
1930    
1931                    // TODO support H2
1932                    // Default query of query DB
1933                    /*
1934                     * setDatasource(datasources, "_queryofquerydb" ,"org.h2.Driver" ,"" ,""
1935                     * ,-1 ,"jdbc:h2:.;MODE=HSQLDB" ,"sa" ,"" ,-1 ,-1 ,true ,true
1936                     * ,DataSource.ALLOW_ALL, new StructImpl() );
1937                     */
1938                    // Default query of query DB
1939                    setDatasource(config, datasources, "_queryofquerydb", "org.hsqldb.jdbcDriver", "", "", -1, "jdbc:hsqldb:.", "sa", "", -1, -1, 60000, true, true, DataSource.ALLOW_ALL,
1940                                    false, false, null, new StructImpl());
1941    
1942                    SecurityManager sm = config.getSecurityManager();
1943                    short access = sm.getAccess(SecurityManager.TYPE_DATASOURCE);
1944                    int accessCount = -1;
1945                    if (access == SecurityManager.VALUE_YES)
1946                            accessCount = -1;
1947                    else if (access == SecurityManager.VALUE_NO)
1948                            accessCount = 0;
1949                    else if (access >= SecurityManager.VALUE_1 && access <= SecurityManager.VALUE_10) {
1950                            accessCount = access - SecurityManager.NUMBER_OFFSET;
1951                    }
1952    
1953                    // Databases
1954                    Element databases = getChildByName(doc.getDocumentElement(), "data-sources");
1955                    // if(databases==null)databases=doc.createElement("data-sources");
1956    
1957                    // PSQ
1958                    String strPSQ = databases.getAttribute("psq");
1959                    if (StringUtil.isEmpty(strPSQ)) {
1960                            // prior version was buggy, was the opposite
1961                            strPSQ = databases.getAttribute("preserve-single-quote");
1962                            if (!StringUtil.isEmpty(strPSQ)) {
1963                                    Boolean b = Caster.toBoolean(strPSQ, null);
1964                                    if (b != null)
1965                                            strPSQ = b.booleanValue() ? "false" : "true";
1966                            }
1967                    }
1968                    if (access != SecurityManager.VALUE_NO && !StringUtil.isEmpty(strPSQ)) {
1969                            config.setPSQL(toBoolean(strPSQ, true));
1970                    }
1971                    else if (hasCS)
1972                            config.setPSQL(configServer.getPSQL());
1973    
1974                    // Data Sources
1975                    Element[] dataSources = getChildren(databases, "data-source");
1976                    if (accessCount == -1)
1977                            accessCount = dataSources.length;
1978                    if (dataSources.length < accessCount)
1979                            accessCount = dataSources.length;
1980    
1981                    // if(hasAccess) {
1982                    for (int i = 0; i < accessCount; i++) {
1983                            Element dataSource = dataSources[i];
1984                            if (dataSource.hasAttribute("database")) {
1985                                    setDatasourceEL(config, datasources, dataSource.getAttribute("name"), dataSource.getAttribute("class"), dataSource.getAttribute("host"),
1986                                                    dataSource.getAttribute("database"), toInt(dataSource.getAttribute("port"), -1), dataSource.getAttribute("dsn"), dataSource.getAttribute("username"),
1987                                                    decrypt(dataSource.getAttribute("password")), toInt(dataSource.getAttribute("connectionLimit"), -1),
1988                                                    toInt(dataSource.getAttribute("connectionTimeout"), -1), toLong(dataSource.getAttribute("metaCacheTimeout"), 60000),
1989                                                    toBoolean(dataSource.getAttribute("blob"), true), toBoolean(dataSource.getAttribute("clob"), true),
1990                                                    toInt(dataSource.getAttribute("allow"), DataSource.ALLOW_ALL), toBoolean(dataSource.getAttribute("validate"), false),
1991                                                    toBoolean(dataSource.getAttribute("storage"), false), dataSource.getAttribute("timezone"), toStruct(dataSource.getAttribute("custom")));
1992                            }
1993                    }
1994                    // }
1995                    config.setDataSources(datasources);
1996            }
1997    
1998            /**
1999             * @param configServer
2000             * @param config
2001             * @param doc
2002             */
2003            /**
2004             * @param configServer
2005             * @param config
2006             * @param doc
2007             */
2008            private static void loadCache(ConfigServerImpl configServer, ConfigImpl config, Document doc) {
2009                    boolean hasCS = configServer != null;
2010                    Map<String, CacheConnection> caches = new HashMap<String, CacheConnection>();
2011    
2012                    boolean hasAccess = ConfigWebUtil.hasAccess(config, SecurityManagerImpl.TYPE_CACHE);
2013                    // print.o("LOAD CACHE:"+hasAccess+":"+hasCS);
2014    
2015                    Element eCache = getChildByName(doc.getDocumentElement(), "cache");
2016    
2017                    // has changes
2018    
2019                    String md5 = getMD5(eCache, hasCS ? configServer.getCacheMD5() : "");
2020                    if (md5.equals(config.getCacheMD5()))
2021                            return;
2022                    config.setCacheMD5(md5);
2023    
2024                    // default query
2025                    String defaultResource = eCache.getAttribute("default-resource");
2026                    if (hasAccess && !StringUtil.isEmpty(defaultResource)) {
2027                            config.setCacheDefaultConnectionName(ConfigImpl.CACHE_DEFAULT_RESOURCE, defaultResource);
2028                    }
2029                    else if (hasCS) {
2030                            if (eCache.hasAttribute("default-resource"))
2031                                    config.setCacheDefaultConnectionName(ConfigImpl.CACHE_DEFAULT_RESOURCE, "");
2032                            else
2033                                    config.setCacheDefaultConnectionName(ConfigImpl.CACHE_DEFAULT_RESOURCE, configServer.getCacheDefaultConnectionName(ConfigImpl.CACHE_DEFAULT_RESOURCE));
2034                    }
2035                    else
2036                            config.setCacheDefaultConnectionName(ConfigImpl.CACHE_DEFAULT_RESOURCE, "");
2037    
2038                    // default function
2039                    String defaultUDF = eCache.getAttribute("default-function");
2040                    if (hasAccess && !StringUtil.isEmpty(defaultUDF)) {
2041                            config.setCacheDefaultConnectionName(ConfigImpl.CACHE_DEFAULT_FUNCTION, defaultUDF);
2042                    }
2043                    else if (hasCS) {
2044                            if (eCache.hasAttribute("default-function"))
2045                                    config.setCacheDefaultConnectionName(ConfigImpl.CACHE_DEFAULT_FUNCTION, "");
2046                            else
2047                                    config.setCacheDefaultConnectionName(ConfigImpl.CACHE_DEFAULT_FUNCTION, configServer.getCacheDefaultConnectionName(ConfigImpl.CACHE_DEFAULT_FUNCTION));
2048                    }
2049                    else
2050                            config.setCacheDefaultConnectionName(ConfigImpl.CACHE_DEFAULT_FUNCTION, "");
2051    
2052                    // default query
2053                    String defaultQuery = eCache.getAttribute("default-query");
2054                    if (hasAccess && !StringUtil.isEmpty(defaultQuery)) {
2055                            config.setCacheDefaultConnectionName(ConfigImpl.CACHE_DEFAULT_QUERY, defaultQuery);
2056                    }
2057                    else if (hasCS) {
2058                            if (eCache.hasAttribute("default-query"))
2059                                    config.setCacheDefaultConnectionName(ConfigImpl.CACHE_DEFAULT_QUERY, "");
2060                            else
2061                                    config.setCacheDefaultConnectionName(ConfigImpl.CACHE_DEFAULT_QUERY, configServer.getCacheDefaultConnectionName(ConfigImpl.CACHE_DEFAULT_QUERY));
2062                    }
2063                    else
2064                            config.setCacheDefaultConnectionName(ConfigImpl.CACHE_DEFAULT_QUERY, "");
2065    
2066                    // default template
2067                    String defaultTemplate = eCache.getAttribute("default-template");
2068                    if (hasAccess && !StringUtil.isEmpty(defaultTemplate)) {
2069                            config.setCacheDefaultConnectionName(ConfigImpl.CACHE_DEFAULT_TEMPLATE, defaultTemplate);
2070                    }
2071                    else if (hasCS) {
2072                            if (eCache.hasAttribute("default-template"))
2073                                    config.setCacheDefaultConnectionName(ConfigImpl.CACHE_DEFAULT_TEMPLATE, "");
2074                            else
2075                                    config.setCacheDefaultConnectionName(ConfigImpl.CACHE_DEFAULT_TEMPLATE, configServer.getCacheDefaultConnectionName(ConfigImpl.CACHE_DEFAULT_TEMPLATE));
2076                    }
2077                    else
2078                            config.setCacheDefaultConnectionName(ConfigImpl.CACHE_DEFAULT_TEMPLATE, "");
2079    
2080                    // default object
2081                    String defaultObject = eCache.getAttribute("default-object");
2082                    if (hasAccess && !StringUtil.isEmpty(defaultObject)) {
2083                            config.setCacheDefaultConnectionName(ConfigImpl.CACHE_DEFAULT_OBJECT, defaultObject);
2084                    }
2085                    else if (hasCS) {
2086                            if (eCache.hasAttribute("default-object"))
2087                                    config.setCacheDefaultConnectionName(ConfigImpl.CACHE_DEFAULT_OBJECT, "");
2088                            else
2089                                    config.setCacheDefaultConnectionName(ConfigImpl.CACHE_DEFAULT_OBJECT, configServer.getCacheDefaultConnectionName(ConfigImpl.CACHE_DEFAULT_OBJECT));
2090                    }
2091                    else
2092                            config.setCacheDefaultConnectionName(ConfigImpl.CACHE_DEFAULT_OBJECT, "");
2093    
2094                    // cache connections
2095                    Element[] eConnections = getChildren(eCache, "connection");
2096    
2097                    // if(hasAccess) {
2098                    String name, clazzName;
2099                    CacheConnection cc;
2100                    Class cacheClazz;
2101                    // caches
2102                    if (hasAccess)
2103                            for (int i = 0; i < eConnections.length; i++) {
2104                                    Element eConnection = eConnections[i];
2105                                    name = eConnection.getAttribute("name");
2106                                    clazzName = eConnection.getAttribute("class");
2107                                    if (clazzName != null)
2108                                            clazzName = clazzName.trim();
2109    
2110                                    //
2111                                    try {
2112    
2113                                            // Workaround for old EHCacheLite class defintion
2114                                            if ("railo.extension.io.cache.eh.EHCacheLite".equals(clazzName))
2115                                                    cacheClazz = EHCacheLite.class;
2116                                            else
2117                                                    cacheClazz = ClassUtil.loadClass(config.getClassLoader(), clazzName);
2118    
2119                                            cc = new CacheConnectionImpl(config, name, cacheClazz, toStruct(eConnection.getAttribute("custom")), Caster.toBooleanValue(
2120                                                            eConnection.getAttribute("read-only"), false), Caster.toBooleanValue(eConnection.getAttribute("storage"), false));
2121                                            if (!StringUtil.isEmpty(name)) {
2122                                                    caches.put(name.toLowerCase(), cc);
2123                                            }
2124                                            else
2125                                                    SystemOut.print(config.getErrWriter(), "missing cache name");
2126    
2127                                    }
2128                                    catch (ClassException ce) {
2129                                            SystemOut.print(config.getErrWriter(), ce.getMessage());
2130                                    }
2131                                    catch (IOException e) {
2132                                            SystemOut.print(config.getErrWriter(), e.getMessage());
2133                                    }
2134                            }
2135                    // }
2136    
2137                    // call static init once per driver
2138                    {
2139                            // group by classes
2140                            Map _caches = new HashMap();
2141                            Iterator it = caches.entrySet().iterator();
2142                            Map.Entry entry;
2143                            ArrayList list;
2144                            while (it.hasNext()) {
2145                                    entry = (Entry) it.next();
2146                                    cc = (CacheConnection) entry.getValue();
2147                                    list = (ArrayList) _caches.get(cc.getClazz());
2148                                    if (list == null) {
2149                                            list = new ArrayList();
2150                                            _caches.put(cc.getClazz(), list);
2151                                    }
2152                                    list.add(cc);
2153                            }
2154    
2155                            // call
2156                            it = _caches.entrySet().iterator();
2157                            Class clazz;
2158                            while (it.hasNext()) {
2159                                    entry = (Entry) it.next();
2160                                    list = (ArrayList) entry.getValue();
2161                                    clazz = (Class) entry.getKey();
2162                                    try {
2163                                            Method m = clazz.getMethod("init", new Class[] { Config.class, String[].class, Struct[].class });
2164    
2165                                            m.invoke(null, new Object[] { config, _toCacheNames(list), _toArguments(list) });
2166                                    }
2167                                    catch (InvocationTargetException e) {
2168                                            e.getTargetException().printStackTrace();
2169                                    }
2170                                    catch (RuntimeException e) {
2171                                            e.printStackTrace();
2172                                    }
2173                                    catch (NoSuchMethodException e) {
2174                                            SystemOut.print(config.getErrWriter(), "missing method [public static init(Config,String[],Struct[]):void] for class [" + clazz.getName() + "] ");
2175                                    }
2176                                    catch (Throwable e) {
2177                                            e.printStackTrace();
2178                                    }
2179                            }
2180                    }
2181    
2182                    // Copy Parent caches as readOnly
2183                    if (hasCS) {
2184                            Map<String, CacheConnection> ds = configServer.getCacheConnections();
2185                            Iterator<Entry<String, CacheConnection>> it = ds.entrySet().iterator();
2186                            Entry<String, CacheConnection> entry;
2187                            while (it.hasNext()) {
2188                                    entry = it.next();
2189                                    cc = entry.getValue();
2190                                    if (!caches.containsKey(entry.getKey()))
2191                                            caches.put(entry.getKey(), new ServerCacheConnection(configServer, cc));
2192                            }
2193                    }
2194                    config.setCaches(caches);
2195            }
2196    
2197            private static String getMD5(Node node, String parentMD5) {
2198                    try {
2199                            return MD5.getDigestAsString(XMLCaster.toString(node, "") + ":" + parentMD5);
2200                    }
2201                    catch (IOException e) {
2202                            return "";
2203                    }
2204            }
2205    
2206            private static void loadGatewayEL(ConfigServerImpl configServer, ConfigImpl config, Document doc) {
2207                    try {
2208                            loadGateway(configServer, config, doc);
2209                    }
2210                    catch (Throwable t) {
2211                            t.printStackTrace();
2212                    }
2213            }
2214    
2215            private static void loadGateway(ConfigServerImpl configServer, ConfigImpl config, Document doc) throws IOException {
2216                    boolean hasCS = configServer != null;
2217                    if (!hasCS)
2218                            return;
2219                    ConfigWebImpl cw = (ConfigWebImpl) config;
2220    
2221                    Map<String, GatewayEntry> mapGateways = new HashMap<String, GatewayEntry>();
2222    
2223                    Element eGateWay = getChildByName(doc.getDocumentElement(), "gateways");
2224    
2225                    String strCFCDirectory = ConfigWebUtil.translateOldPath(eGateWay.getAttribute("cfc-directory"));
2226                    if (StringUtil.isEmpty(strCFCDirectory))
2227                            strCFCDirectory = "{railo-config}/gateway/";
2228    
2229                    // Deploy Dir
2230                    // Resource cfcDirectory =
2231                    // ConfigWebUtil.getFile(configDir,strCFCDirectory,
2232                    // "gateway",configDir,FileUtil.TYPE_DIR,config);
2233    
2234                    boolean hasAccess = ConfigWebUtil.hasAccess(config, SecurityManagerImpl.TYPE_GATEWAY);
2235    
2236                    // Logger
2237                    String strLogger = hasAccess ? eGateWay.getAttribute("log") : "";
2238                    // if(StringUtil.isEmpty(strLogger) && hasCS)
2239                    // strLogger=configServer.getGatewayLogger().getSource();
2240                    if (StringUtil.isEmpty(strLogger))
2241                            strLogger = "{railo-config}/logs/gateway.log";
2242    
2243                    int logLevel = LogUtil.toIntType(eGateWay.getAttribute("log-level"), -1);
2244                    if (logLevel == -1 && hasCS)
2245                            logLevel = configServer.getMailLogger().getLogLevel();
2246                    if (logLevel == -1)
2247                            logLevel = Log.LEVEL_ERROR;
2248                    cw.setGatewayLogger(ConfigWebUtil.getLogAndSource(configServer, config, strLogger, hasAccess, logLevel));
2249    
2250                    GatewayEntry ge;
2251    
2252                    // cache connections
2253                    Element[] gateways = getChildren(eGateWay, "gateway");
2254    
2255                    // if(hasAccess) {
2256                    String id;
2257                    GatewayEngineImpl engine = cw.getGatewayEngine();
2258                    // engine.reset();
2259    
2260                    // caches
2261                    if (hasAccess) {
2262                            for (int i = 0; i < gateways.length; i++) {
2263                                    Element eConnection = gateways[i];
2264                                    id = eConnection.getAttribute("id").trim().toLowerCase();
2265    
2266                                    ge = new GatewayEntryImpl(engine, id, eConnection.getAttribute("class"), eConnection.getAttribute("cfc-path"), eConnection.getAttribute("listener-cfc-path"),
2267                                                    eConnection.getAttribute("startup-mode"), toStruct(eConnection.getAttribute("custom")), Caster.toBooleanValue(eConnection.getAttribute("read-only"), false));
2268    
2269                                    if (!StringUtil.isEmpty(id)) {
2270                                            mapGateways.put(id.toLowerCase(), ge);
2271                                    }
2272                                    else
2273                                            SystemOut.print(config.getErrWriter(), "missing id");
2274                            }
2275                            cw.setGatewayEntries(mapGateways);
2276                    }
2277                    else {
2278                            cw.getGatewayEngine().clear();
2279                    }
2280            }
2281    
2282            private static Struct[] _toArguments(ArrayList list) {
2283                    Iterator it = list.iterator();
2284                    Struct[] args = new Struct[list.size()];
2285                    CacheConnection cc;
2286                    int index = 0;
2287                    while (it.hasNext()) {
2288                            cc = (CacheConnection) it.next();
2289                            args[index++] = cc.getCustom();
2290                    }
2291                    return args;
2292            }
2293    
2294            private static String[] _toCacheNames(ArrayList list) {
2295                    Iterator it = list.iterator();
2296                    String[] names = new String[list.size()];
2297                    CacheConnection cc;
2298                    int index = 0;
2299                    while (it.hasNext()) {
2300                            cc = (CacheConnection) it.next();
2301                            names[index++] = cc.getName();
2302                    }
2303                    return names;
2304            }
2305    
2306            public static String decrypt(String str) {
2307                    if (StringUtil.isEmpty(str) || !StringUtil.startsWithIgnoreCase(str, "encrypted:"))
2308                            return str;
2309                    str = str.substring(10);
2310                    return new BlowfishEasy("sdfsdfs").decryptString(str);
2311            }
2312    
2313            public static String encrypt(String str) {
2314                    if (StringUtil.isEmpty(str))
2315                            return "";
2316                    if (StringUtil.startsWithIgnoreCase(str, "encrypted:"))
2317                            return str;
2318                    return "encrypted:" + new BlowfishEasy("sdfsdfs").encryptString(str);
2319            }
2320    
2321            private static Struct toStruct(String str) {
2322    
2323                    Struct sct = new StructImpl();
2324                    try {
2325                            String[] arr = ListUtil.toStringArray(ListUtil.listToArrayRemoveEmpty(str, '&'));
2326    
2327                            String[] item;
2328                            for (int i = 0; i < arr.length; i++) {
2329                                    item = ListUtil.toStringArray(ListUtil.listToArrayRemoveEmpty(arr[i], '='));
2330                                    if (item.length == 2)
2331                                            sct.setEL(KeyImpl.init(URLDecoder.decode(item[0], true).trim()), URLDecoder.decode(item[1], true));
2332                                    else if (item.length == 1)
2333                                            sct.setEL(KeyImpl.init(URLDecoder.decode(item[0], true).trim()), "");
2334                            }
2335                    }
2336                    catch (PageException ee) {
2337                    }
2338    
2339                    return sct;
2340            }
2341    
2342            private static void setDatasource(ConfigImpl config, Map<String, DataSource> datasources, String datasourceName, String className, String server, String databasename,
2343                            int port, String dsn, String user, String pass, int connectionLimit, int connectionTimeout, long metaCacheTimeout, boolean blob, boolean clob, int allow,
2344                            boolean validate, boolean storage, String timezone, Struct custom) throws ClassException {
2345    
2346                    datasources.put(datasourceName.toLowerCase(),
2347                                    new DataSourceImpl(datasourceName, className, server, dsn, databasename, port, user, pass, connectionLimit, connectionTimeout, metaCacheTimeout, blob, clob, allow,
2348                                                    custom, false, validate, storage, StringUtil.isEmpty(timezone, true) ? null : TimeZoneUtil.toTimeZone(timezone, null)));
2349    
2350            }
2351    
2352            private static void setDatasourceEL(ConfigImpl config, Map<String, DataSource> datasources, String datasourceName, String className, String server, String databasename,
2353                            int port, String dsn, String user, String pass, int connectionLimit, int connectionTimeout, long metaCacheTimeout, boolean blob, boolean clob, int allow,
2354                            boolean validate, boolean storage, String timezone, Struct custom) {
2355                    try {
2356                            setDatasource(config, datasources, datasourceName, className, server, databasename, port, dsn, user, pass, connectionLimit, connectionTimeout, metaCacheTimeout, blob,
2357                                            clob, allow, validate, storage, timezone, custom);
2358                    }
2359                    catch (Throwable t) {
2360                    }
2361            }
2362    
2363            /**
2364             * @param configServer
2365             * @param config
2366             * @param doc
2367             * @throws IOException
2368             */
2369            private static void loadCustomTagsMappings(ConfigServerImpl configServer, ConfigImpl config, Document doc, int mode) {
2370    
2371                    boolean hasAccess = ConfigWebUtil.hasAccess(config, SecurityManager.TYPE_CUSTOM_TAG);
2372                    boolean hasCS = configServer != null;
2373    
2374                    Element customTag = getChildByName(doc.getDocumentElement(), "custom-tag");
2375                    Element[] ctMappings = getChildren(customTag, "mapping");
2376                    // String virtualx="/custom-tag/";
2377    
2378                    // do patch cache
2379                    String strDoPathcache = customTag.getAttribute("use-cache-path");
2380                    if (hasAccess && !StringUtil.isEmpty(strDoPathcache, true)) {
2381                            config.setUseCTPathCache(Caster.toBooleanValue(strDoPathcache.trim(), true));
2382                    }
2383                    else if (hasCS) {
2384                            config.setUseCTPathCache(configServer.useCTPathCache());
2385                    }
2386    
2387                    // do custom tag local search
2388                    if (mode == ConfigImpl.MODE_STRICT) {
2389                            config.setDoLocalCustomTag(false);
2390                    }
2391                    else {
2392                            String strDoCTLocalSearch = customTag.getAttribute("custom-tag-local-search");
2393                            if (hasAccess && !StringUtil.isEmpty(strDoCTLocalSearch)) {
2394                                    config.setDoLocalCustomTag(Caster.toBooleanValue(strDoCTLocalSearch.trim(), true));
2395                            }
2396                            else if (hasCS) {
2397                                    config.setDoLocalCustomTag(configServer.doLocalCustomTag());
2398                            }
2399                    }
2400    
2401                    // do custom tag deep search
2402                    if (mode == ConfigImpl.MODE_STRICT) {
2403                            config.setDoCustomTagDeepSearch(false);
2404                    }
2405                    else {
2406                            String strDoCTDeepSearch = customTag.getAttribute("custom-tag-deep-search");
2407                            if (hasAccess && !StringUtil.isEmpty(strDoCTDeepSearch)) {
2408                                    config.setDoCustomTagDeepSearch(Caster.toBooleanValue(strDoCTDeepSearch.trim(), false));
2409                            }
2410                            else if (hasCS) {
2411                                    config.setDoCustomTagDeepSearch(configServer.doCustomTagDeepSearch());
2412                            }
2413                    }
2414    
2415                    // extensions
2416                    if (mode == ConfigImpl.MODE_STRICT) {
2417                            config.setCustomTagExtensions(new String[] { "cfc" });
2418                    }
2419                    else {
2420                            String strExtensions = customTag.getAttribute("extensions");
2421                            if (hasAccess && !StringUtil.isEmpty(strExtensions)) {
2422                                    try {
2423                                            String[] arr = ListUtil.toStringArray(ListUtil.listToArrayRemoveEmpty(strExtensions, ","));
2424                                            config.setCustomTagExtensions(ListUtil.trimItems(arr));
2425                                    }
2426                                    catch (PageException e) {
2427                                    }
2428                            }
2429                            else if (hasCS) {
2430                                    config.setCustomTagExtensions(configServer.getCustomTagExtensions());
2431                            }
2432                    }
2433    
2434                    // Web Mapping
2435                    boolean hasSet = false;
2436                    Mapping[] mappings = null;
2437                    if (hasAccess && ctMappings.length > 0) {
2438                            mappings = new Mapping[ctMappings.length];
2439                            for (int i = 0; i < ctMappings.length; i++) {
2440                                    Element ctMapping = ctMappings[i];
2441                                    String physical = ctMapping.getAttribute("physical");
2442                                    String archive = ctMapping.getAttribute("archive");
2443                                    boolean readonly = toBoolean(ctMapping.getAttribute("readonly"), false);
2444                                    boolean hidden = toBoolean(ctMapping.getAttribute("hidden"), false);
2445                                    //boolean trusted = toBoolean(ctMapping.getAttribute("trusted"), false);
2446                                    short inspTemp=inspectTemplate(ctMapping);
2447                                    int clMaxEl = toInt(ctMapping.getAttribute("classloader-max-elements"), 100);
2448    
2449                                    String primary = ctMapping.getAttribute("primary");
2450    
2451                                    boolean physicalFirst = archive == null || !primary.equalsIgnoreCase("archive");
2452                                    hasSet = true;
2453                                    mappings[i] = new MappingImpl(config, ConfigWebAdmin.createVirtual(ctMapping), physical, archive, inspTemp, physicalFirst, hidden, readonly, true, false, true,
2454                                                    null, clMaxEl);
2455                                    // print.out(mappings[i].isPhysicalFirst());
2456                            }
2457    
2458                            config.setCustomTagMappings(mappings);
2459    
2460                    }
2461    
2462                    // Server Mapping
2463                    if (hasCS) {
2464                            Mapping[] originals = configServer.getCustomTagMappings();
2465                            Mapping[] clones = new Mapping[originals.length];
2466                            LinkedHashMap map = new LinkedHashMap();
2467                            Mapping m;
2468                            for (int i = 0; i < clones.length; i++) {
2469                                    m = ((MappingImpl) originals[i]).cloneReadOnly(config);
2470                                    map.put(toKey(m), m);
2471                                    // clones[i]=((MappingImpl)m[i]).cloneReadOnly(config);
2472                            }
2473    
2474                            if (mappings != null) {
2475                                    for (int i = 0; i < mappings.length; i++) {
2476                                            m = mappings[i];
2477                                            map.put(toKey(m), m);
2478                                    }
2479                            }
2480                            if (originals.length > 0) {
2481                                    clones = new Mapping[map.size()];
2482                                    Iterator it = map.entrySet().iterator();
2483                                    Map.Entry entry;
2484                                    int index = 0;
2485                                    while (it.hasNext()) {
2486                                            entry = (Entry) it.next();
2487                                            clones[index++] = (Mapping) entry.getValue();
2488                                            // print.out("c:"+clones[index-1]);
2489                                    }
2490                                    hasSet = true;
2491                                    // print.err("set:"+clones.length);
2492    
2493                                    config.setCustomTagMappings(clones);
2494                            }
2495                    }
2496    
2497                    if (!hasSet) {
2498                            // MappingImpl m=new
2499                            // MappingImpl(config,"/default-customtags/","{railo-web}/customtags/",null,false,true,false,false,true,false,true);
2500                            // config.setCustomTagMappings(new
2501                            // Mapping[]{m.cloneReadOnly(config)});
2502                    }
2503    
2504            }
2505    
2506            private static Object toKey(Mapping m) {
2507                    if (!StringUtil.isEmpty(m.getStrPhysical(), true))
2508                            return m.getStrPhysical().toLowerCase().trim();
2509                    return (m.getStrPhysical() + ":" + m.getStrArchive()).toLowerCase();
2510            }
2511    
2512            /**
2513             * @param configServer
2514             * @param config
2515             * @param doc
2516             */
2517            private static void loadRailoConfig(ConfigServerImpl configServer, ConfigImpl config, Document doc) {
2518                    // password
2519                    Element railoConfiguration = doc.getDocumentElement();
2520                    String password = railoConfiguration.getAttribute("password");
2521                    if (!StringUtil.isEmpty(password)) {
2522                            config.setPassword(new BlowfishEasy("tpwisgh").decryptString(password));
2523                    }
2524                    else if (configServer != null) {
2525                            config.setPassword(configServer.getDefaultPassword());
2526                    }
2527    
2528                    if (config instanceof ConfigServerImpl) {
2529                            password = railoConfiguration.getAttribute("default-password");
2530                            if (!StringUtil.isEmpty(password))
2531                                    ((ConfigServerImpl) config).setDefaultPassword(new BlowfishEasy("tpwisgh").decryptString(password));
2532                    }
2533    
2534                    // mode
2535                    String mode = railoConfiguration.getAttribute("mode");
2536                    if (!StringUtil.isEmpty(mode, true)) {
2537                            mode = mode.trim();
2538                            if ("custom".equalsIgnoreCase(mode))
2539                                    config.setMode(ConfigImpl.MODE_CUSTOM);
2540                            if ("strict".equalsIgnoreCase(mode))
2541                                    config.setMode(ConfigImpl.MODE_STRICT);
2542                    }
2543                    else if (configServer != null) {
2544                            config.setMode(configServer.getMode());
2545                    }
2546    
2547                    // check config file for changes
2548                    String cFc = railoConfiguration.getAttribute("check-for-changes");
2549                    if (!StringUtil.isEmpty(cFc, true)) {
2550                            config.setCheckForChangesInConfigFile(Caster.toBooleanValue(cFc.trim(), false));
2551                    }
2552                    else if (configServer != null) {
2553                            config.setCheckForChangesInConfigFile(configServer.checkForChangesInConfigFile());
2554                    }
2555            }
2556    
2557            /*
2558             * private static void loadLabel(ConfigServerImpl configServer, ConfigImpl
2559             * config, Document doc) { // do only for web config if(configServer!=null
2560             * && config instanceof ConfigWebImpl) { ConfigWebImpl cs=(ConfigWebImpl)
2561             * config; String hash=SystemUtil.hash(cs.getServletContext());
2562             * config.setLabel(hash);
2563             * 
2564             * Map<String, String> labels = configServer.getLabels(); if(labels!=null) {
2565             * String label = labels.get(hash); if(!StringUtil.isEmpty(label)) {
2566             * print.o("label:"+label); config.setLabel(label);
2567             * config.getFactory().setLabel(label); } } } }
2568             */
2569    
2570            private static void loadTag(ConfigServerImpl configServer, ConfigImpl config, Document doc) {
2571                    Element parent = getChildByName(doc.getDocumentElement(), "tags");
2572                    Element[] tags = getChildren(parent, "tag");
2573                    Element tag;
2574    
2575                    String nss, ns, n, c;
2576                    if (tags != null) {
2577                            for (int i = 0; i < tags.length; i++) {
2578                                    tag = tags[i];
2579                                    ns = tag.getAttribute("namespace");
2580                                    nss = tag.getAttribute("namespace-seperator");
2581                                    n = tag.getAttribute("name");
2582                                    c = tag.getAttribute("class");
2583                                    config.addTag(ns, nss, n, c);
2584                            }
2585                    }
2586    
2587            }
2588    
2589            private static void loadTempDirectory(ConfigServerImpl configServer, ConfigImpl config, Document doc, boolean isReload) throws ExpressionException {
2590                    Resource configDir = config.getConfigDir();
2591                    boolean hasCS = configServer != null;
2592    
2593                    Element fileSystem = getChildByName(doc.getDocumentElement(), "file-system");
2594                    if (fileSystem == null)
2595                            fileSystem = getChildByName(doc.getDocumentElement(), "filesystem");
2596    
2597                    String strTempDirectory = null;
2598                    if (fileSystem != null)
2599                            strTempDirectory = ConfigWebUtil.translateOldPath(fileSystem.getAttribute("temp-directory"));
2600    
2601                    Resource cst = null;
2602                    // Temp Dir
2603                    if (!StringUtil.isEmpty(strTempDirectory))
2604                            cst = ConfigWebUtil.getFile(configDir, strTempDirectory, null, configDir, FileUtil.TYPE_DIR, config);
2605    
2606                    if (cst == null && hasCS)
2607                            cst = configServer.getTempDirectory();
2608    
2609                    if (cst == null)
2610                            cst = ConfigWebUtil.getFile(configDir, "temp", null, configDir, FileUtil.TYPE_DIR, config);
2611    
2612                    config.setTempDirectory(cst, !isReload);
2613    
2614            }
2615    
2616            /**
2617             * @param configServer
2618             * @param config
2619             * @param doc
2620             * @throws ExpressionException
2621             * @throws TagLibException
2622             * @throws FunctionLibException
2623             */
2624            private static void loadFilesystem(ConfigServerImpl configServer, ConfigImpl config, Document doc, boolean doNew) throws ExpressionException, TagLibException,
2625                            FunctionLibException {
2626    
2627                    if (configServer != null) {
2628                            Resource src = configServer.getConfigDir().getRealResource("distribution");
2629                            Resource trg = config.getConfigDir().getRealResource("context/");
2630                            copyContextFiles(src, trg);
2631                    }
2632    
2633                    Resource configDir = config.getConfigDir();
2634    
2635                    boolean hasCS = configServer != null;
2636    
2637                    Element fileSystem = getChildByName(doc.getDocumentElement(), "file-system");
2638                    if (fileSystem == null)
2639                            fileSystem = getChildByName(doc.getDocumentElement(), "filesystem");
2640    
2641                    String strAllowRealPath = null;
2642                    String strDeployDirectory = null;
2643                    // String strTempDirectory=null;
2644                    String strTLDDirectory = null;
2645                    String strFLDDirectory = null;
2646                    String strTagDirectory = null;
2647                    String strFunctionDirectory = null;
2648    
2649                    if (fileSystem != null) {
2650                            strAllowRealPath = ConfigWebUtil.translateOldPath(fileSystem.getAttribute("allow-realpath"));
2651                            strDeployDirectory = ConfigWebUtil.translateOldPath(fileSystem.getAttribute("deploy-directory"));
2652                            // strTempDirectory=ConfigWebUtil.translateOldPath(fileSystem.getAttribute("temp-directory"));
2653                            strTLDDirectory = ConfigWebUtil.translateOldPath(fileSystem.getAttribute("tld-directory"));
2654                            strFLDDirectory = ConfigWebUtil.translateOldPath(fileSystem.getAttribute("fld-directory"));
2655                            strTagDirectory = ConfigWebUtil.translateOldPath(fileSystem.getAttribute("tag-directory"));
2656                            strFunctionDirectory = ConfigWebUtil.translateOldPath(fileSystem.getAttribute("function-directory"));
2657                    }
2658                    if (StringUtil.isEmpty(strFLDDirectory))
2659                            strFLDDirectory = "{railo-config}/library/fld/";
2660                    if (StringUtil.isEmpty(strTLDDirectory))
2661                            strTLDDirectory = "{railo-config}/library/tld/";
2662                    if (StringUtil.isEmpty(strFunctionDirectory))
2663                            strFunctionDirectory = "{railo-config}/library/function/";
2664                    if (StringUtil.isEmpty(strTagDirectory))
2665                            strTagDirectory = "{railo-config}/library/tag/";
2666    
2667                    // Deploy Dir
2668                    // gateway must run in server env
2669                    // if(!(config instanceof ConfigServer)) {
2670                    Resource dd = ConfigWebUtil.getFile(configDir, strDeployDirectory, "cfclasses", configDir, FileUtil.TYPE_DIR, config);
2671                    config.setDeployDirectory(dd);
2672                    // }
2673    
2674                    // Temp Dir
2675                    /*
2676                     * if(!StringUtil.isEmpty(strTempDirectory)) {
2677                     * config.setTempDirectory(ConfigWebUtil
2678                     * .getFile(configDir,strTempDirectory, null, // create no default
2679                     * configDir,FileUtil.TYPE_DIR,config)); } else if(hasCS) {
2680                     * config.setTempDirectory(configServer.getTempDirectory()); }
2681                     * if(config.getTempDirectory()==null) {
2682                     * config.setTempDirectory(ConfigWebUtil.getFile(configDir,"temp", null,
2683                     * // create no default configDir,FileUtil.TYPE_DIR,config)); }
2684                     */
2685    
2686                    // TLD Dir
2687                    // if(hasCS) {
2688                    // config.setTldFile(configServer.getTldFile());
2689                    // }
2690                    if (strTLDDirectory != null) {
2691                            Resource tld = ConfigWebUtil.getFile(config, configDir, strTLDDirectory, FileUtil.TYPE_DIR);
2692                            // print.err(tld);
2693                            if (tld != null)
2694                                    config.setTldFile(tld);
2695                    }
2696    
2697                    // Tag Directory
2698                    if (strTagDirectory != null) {
2699                            Resource dir = ConfigWebUtil.getFile(config, configDir, strTagDirectory, FileUtil.TYPE_DIR);
2700                            createTagFiles(config, configDir, dir, doNew);
2701                            if (dir != null) {
2702                                    config.setTagDirectory(dir);
2703                            }
2704                    }
2705    
2706                    // allow realpath
2707                    if (hasCS) {
2708                            config.setAllowRealPath(configServer.allowRealPath());
2709                    }
2710                    if (!StringUtil.isEmpty(strAllowRealPath, true)) {
2711                            config.setAllowRealPath(Caster.toBooleanValue(strAllowRealPath, true));
2712                    }
2713    
2714                    // FLD Dir
2715                    // if(hasCS) {
2716                    // config.setFldFile(configServer.getFldFile());
2717                    // }
2718                    if (strFLDDirectory != null) {
2719                            Resource fld = ConfigWebUtil.getFile(config, configDir, strFLDDirectory, FileUtil.TYPE_DIR);
2720                            if (fld != null)
2721                                    config.setFldFile(fld);
2722                    }
2723    
2724                    // Function Directory
2725                    if (strFunctionDirectory != null) {
2726                            Resource dir = ConfigWebUtil.getFile(config, configDir, strFunctionDirectory, FileUtil.TYPE_DIR);
2727                            createFunctionFiles(config, configDir, dir, doNew);
2728                            if (dir != null)
2729                                    config.setFunctionDirectory(dir);
2730                    }
2731    
2732                    /*
2733                     * / Function Dir if(strFunctionDirectory!=null) { Resource
2734                     * func=ConfigWebUtil
2735                     * .getFile(config,configDir,strFunctionDirectory,FileUtil.TYPE_DIR);
2736                     * if(func!=null) config.setFldFile(fld); }
2737                     */
2738    
2739            }
2740    
2741            private static void createTagFiles(Config config, Resource configDir, Resource dir, boolean doNew) {
2742                    if (config instanceof ConfigServer) {
2743    
2744                            // Dump
2745                            Resource f = dir.getRealResource("Dump.cfc");
2746                            if (!f.exists() || doNew)
2747                                    createFileFromResourceEL("/resource/library/tag/Dump.cfc", f);
2748    
2749                            // MediaPlayer
2750                            f = dir.getRealResource("MediaPlayer.cfc");
2751                            if (!f.exists() || doNew)
2752                                    createFileFromResourceEL("/resource/library/tag/MediaPlayer.cfc", f);
2753                            Resource build = dir.getRealResource("build");
2754                            if (!build.exists())
2755                                    build.mkdirs();
2756                            String[] names = new String[] { "_background.png", "_bigplay.png", "_controls.png", "_loading.gif", "_player.swf", "_player.xap", "background_png.cfm",
2757                                            "bigplay_png.cfm", "controls_png.cfm", "jquery.js.cfm", "loading_gif.cfm", "mediaelement-and-player.min.js.cfm", "mediaelementplayer.min.css.cfm",
2758                                            "player.swf.cfm", "player.xap.cfm" };
2759                            for (int i = 0; i < names.length; i++) {
2760                                    f = build.getRealResource(names[i]);
2761                                    if (!f.exists() || doNew)
2762                                            createFileFromResourceEL("/resource/library/tag/build/" + names[i], f);
2763    
2764                            }
2765    
2766                            // AJAX
2767                            AjaxFactory.deployTags(dir, doNew);
2768    
2769                    }
2770            }
2771    
2772            private static void createFunctionFiles(Config config, Resource configDir, Resource dir, boolean doNew) {
2773    
2774                    if (config instanceof ConfigServer) {
2775                            Resource f = dir.getRealResource("writeDump.cfm");
2776                            if (!f.exists() || doNew)
2777                                    createFileFromResourceEL("/resource/library/function/writeDump.cfm", f);
2778    
2779                            f = dir.getRealResource("dump.cfm");
2780                            if (!f.exists() || doNew)
2781                                    createFileFromResourceEL("/resource/library/function/dump.cfm", f);
2782    
2783                            f = dir.getRealResource("location.cfm");
2784                            if (!f.exists() || doNew)
2785                                    createFileFromResourceEL("/resource/library/function/location.cfm", f);
2786    
2787                            f = dir.getRealResource("threadJoin.cfm");
2788                            if (!f.exists() || doNew)
2789                                    createFileFromResourceEL("/resource/library/function/threadJoin.cfm", f);
2790    
2791                            f = dir.getRealResource("threadTerminate.cfm");
2792                            if (!f.exists() || doNew)
2793                                    createFileFromResourceEL("/resource/library/function/threadTerminate.cfm", f);
2794    
2795                            f = dir.getRealResource("throw.cfm");
2796                            if (!f.exists() || doNew)
2797                                    createFileFromResourceEL("/resource/library/function/throw.cfm", f);
2798    
2799                            f = dir.getRealResource("trace.cfm");
2800                            if (!f.exists() || doNew)
2801                                    createFileFromResourceEL("/resource/library/function/trace.cfm", f);
2802    
2803                            f = dir.getRealResource("transactionCommit.cfm");
2804                            if (!f.exists() || doNew)
2805                                    createFileFromResourceEL("/resource/library/function/transactionCommit.cfm", f);
2806    
2807                            f = dir.getRealResource("transactionRollback.cfm");
2808                            if (!f.exists() || doNew)
2809                                    createFileFromResourceEL("/resource/library/function/transactionRollback.cfm", f);
2810    
2811                            f = dir.getRealResource("transactionSetsavepoint.cfm");
2812                            if (!f.exists() || doNew)
2813                                    createFileFromResourceEL("/resource/library/function/transactionSetsavepoint.cfm", f);
2814    
2815                            f = dir.getRealResource("writeLog.cfm");
2816                            if (!f.exists() || doNew)
2817                                    createFileFromResourceEL("/resource/library/function/writeLog.cfm", f);
2818    
2819                            AjaxFactory.deployFunctions(dir, doNew);
2820    
2821                    }
2822            }
2823    
2824            private static void copyContextFiles(Resource src, Resource trg) {
2825                    // directory
2826                    if (src.isDirectory()) {
2827                            if (trg.exists())
2828                                    trg.mkdirs();
2829                            Resource[] children = src.listResources();
2830                            for (int i = 0; i < children.length; i++) {
2831                                    copyContextFiles(children[i], trg.getRealResource(children[i].getName()));
2832                            }
2833                    }
2834                    // file
2835                    else if (src.isFile()) {
2836                            if (src.lastModified() > trg.lastModified()) {
2837                                    try {
2838                                            if (trg.exists())
2839                                                    trg.remove(true);
2840                                            trg.createFile(true);
2841                                            src.copyTo(trg, false);
2842                                    }
2843                                    catch (IOException e) {
2844                                            e.printStackTrace();
2845                                    }
2846                            }
2847    
2848                    }
2849            }
2850    
2851            /**
2852             * @param configServer
2853             * @param config
2854             * @param doc
2855             */
2856            private static void loadUpdate(ConfigServer configServer, Config config, Document doc) {
2857    
2858                    // Server
2859                    if (config instanceof ConfigServer) {
2860                            ConfigServer cs = (ConfigServer) config;
2861                            Element update = getChildByName(doc.getDocumentElement(), "update");
2862    
2863                            if (update != null) {
2864                                    cs.setUpdateType(update.getAttribute("type"));
2865                                    cs.setUpdateLocation(update.getAttribute("location"), null);
2866                            }
2867                    }
2868            }
2869    
2870            private static void loadVideo(ConfigServerImpl configServer, ConfigImpl config, Document doc) throws ApplicationException {
2871    
2872                    Element video = config instanceof ConfigServerImpl ? getChildByName(doc.getDocumentElement(), "video") : null;
2873                    boolean hasCS = configServer != null;
2874                    String str = null;
2875    
2876                    // video-executer
2877                    if (video != null) {
2878                            str = video.getAttribute("video-executer-class");
2879                            if (StringUtil.isEmpty(str))
2880                                    str = video.getAttribute("video-executer");
2881                    }
2882                    if (!StringUtil.isEmpty(str)) {
2883                            try {
2884                                    Class clazz = ClassUtil.loadClass(config.getClassLoader(), str);
2885                                    if (!Reflector.isInstaneOf(clazz, VideoExecuter.class))
2886                                            throw new ApplicationException("class [" + clazz.getName() + "] does not implement interface [" + VideoExecuter.class.getName() + "]");
2887                                    config.setVideoExecuterClass(clazz);
2888    
2889                            }
2890                            catch (ClassException e) {
2891                                    e.printStackTrace();
2892                            }
2893                    }
2894                    else if (hasCS)
2895                            config.setVideoExecuterClass(configServer.getVideoExecuterClass());
2896    
2897            }
2898    
2899            /**
2900             * @param configServer
2901             * @param config
2902             * @param doc
2903             */
2904            private static void loadSetting(ConfigServerImpl configServer, ConfigImpl config, Document doc) {
2905                    boolean hasAccess = ConfigWebUtil.hasAccess(config, SecurityManager.TYPE_SETTING);
2906    
2907                    Element setting = hasAccess ? getChildByName(doc.getDocumentElement(), "setting") : null;
2908                    boolean hasCS = configServer != null;
2909                    String str = null;
2910    
2911                    // suppress whitespace
2912                    str = null;
2913                    if (setting != null) {
2914                            str = setting.getAttribute("suppress-content");
2915                    }
2916                    if (!StringUtil.isEmpty(str) && hasAccess) {
2917                            config.setSuppressContent(toBoolean(str, false));
2918                    }
2919                    else if (hasCS)
2920                            config.setSuppressContent(configServer.isSuppressContent());
2921    
2922                    // CFML Writer
2923                    if (setting != null) {
2924                            str = setting.getAttribute("cfml-writer");
2925                    }
2926                    if (!StringUtil.isEmpty(str) && hasAccess) {
2927                            if ("white-space".equalsIgnoreCase(str))
2928                                    config.setCFMLWriterType(ConfigImpl.CFML_WRITER_WS);
2929                            else if ("white-space-pref".equalsIgnoreCase(str))
2930                                    config.setCFMLWriterType(ConfigImpl.CFML_WRITER_WS_PREF);
2931                            else if ("regular".equalsIgnoreCase(str))
2932                                    config.setCFMLWriterType(ConfigImpl.CFML_WRITER_REFULAR);
2933                            // FUTURE add support for classes implementing CFMLWriter interface
2934                    }
2935                    else if (hasCS)
2936                            config.setCFMLWriterType(configServer.getCFMLWriterType());
2937    
2938                    // No longer supported, replaced with code above
2939                    // suppress whitespace
2940                    /*
2941                     * str=null; if(setting!=null){
2942                     * str=setting.getAttribute("suppress-whitespace");
2943                     * if(StringUtil.isEmpty
2944                     * (str))str=setting.getAttribute("suppresswhitespace"); }
2945                     * if(!StringUtil.isEmpty(str) && hasAccess) {
2946                     * config.setSuppressWhitespace(toBoolean(str,false)); } else
2947                     * if(hasCS)config
2948                     * .setSuppressWhitespace(configServer.isSuppressWhitespace());
2949                     */
2950    
2951                    // show version
2952                    str = null;
2953                    if (setting != null) {
2954                            str = setting.getAttribute("show-version");
2955                            if (StringUtil.isEmpty(str))
2956                                    str = setting.getAttribute("showversion");
2957                    }
2958                    if (!StringUtil.isEmpty(str) && hasAccess) {
2959                            config.setShowVersion(toBoolean(str, true));
2960                    }
2961                    else if (hasCS)
2962                            config.setShowVersion(configServer.isShowVersion());
2963    
2964                    // close connection
2965                    str = null;
2966                    if (setting != null) {
2967                            str = setting.getAttribute("close-connection");
2968                            if (StringUtil.isEmpty(str))
2969                                    str = setting.getAttribute("closeconnection");
2970                    }
2971                    if (!StringUtil.isEmpty(str) && hasAccess) {
2972                            config.setCloseConnection(toBoolean(str, false));
2973                    }
2974                    else if (hasCS)
2975                            config.setCloseConnection(configServer.closeConnection());
2976    
2977                    // content-length
2978                    str = null;
2979                    if (setting != null) {
2980                            str = setting.getAttribute("content-length");
2981                            if (StringUtil.isEmpty(str))
2982                                    str = setting.getAttribute("contentlength");
2983                    }
2984                    if (!StringUtil.isEmpty(str) && hasAccess) {
2985                            config.setContentLength(toBoolean(str, true));
2986                    }
2987                    else if (hasCS)
2988                            config.setContentLength(configServer.contentLength());
2989    
2990                    // buffer-output
2991                    str = null;
2992                    if (setting != null) {
2993                            str = setting.getAttribute("buffer-output");
2994                            if (StringUtil.isEmpty(str))
2995                                    str = setting.getAttribute("bufferoutput");
2996                    }
2997                    Boolean b = Caster.toBoolean(str, null);
2998                    if (b != null && hasAccess) {
2999                            config.setBufferOutput(b.booleanValue());
3000                    }
3001                    else if (hasCS)
3002                            config.setBufferOutput(configServer.getBufferOutput());
3003    
3004                    // allow-compression
3005                    str = null;
3006                    if (setting != null) {
3007                            str = setting.getAttribute("allow-compression");
3008                            if (StringUtil.isEmpty(str))
3009                                    str = setting.getAttribute("allowcompression");
3010                    }
3011                    if (!StringUtil.isEmpty(str) && hasAccess) {
3012                            config.setAllowCompression(toBoolean(str, true));
3013                    }
3014                    else if (hasCS)
3015                            config.setAllowCompression(configServer.allowCompression());
3016    
3017            }
3018    
3019            private static void loadRemoteClient(ConfigServerImpl configServer, ConfigImpl config, Document doc) throws IOException {
3020                    boolean hasAccess = ConfigWebUtil.hasAccess(config, SecurityManagerImpl.TYPE_REMOTE);
3021    
3022                    // SNSN
3023                    // RemoteClientUsage
3024    
3025                    // boolean hasCS=configServer!=null;
3026                    Element _clients = getChildByName(doc.getDocumentElement(), "remote-clients");
3027    
3028                    // usage
3029                    String strUsage = _clients.getAttribute("usage");
3030                    Struct sct;
3031                    if (!StringUtil.isEmpty(strUsage))
3032                            sct = toStruct(strUsage);// config.setRemoteClientUsage(toStruct(strUsage));
3033                    else
3034                            sct = new StructImpl();
3035                    // TODO make this generic
3036                    if (configServer != null) {
3037                            String sync = Caster.toString(configServer.getRemoteClientUsage().get("synchronisation", ""), "");
3038                            if (!StringUtil.isEmpty(sync)) {
3039                                    sct.setEL("synchronisation", sync);
3040                            }
3041                    }
3042                    config.setRemoteClientUsage(sct);
3043    
3044                    // max-threads
3045                    int maxThreads = Caster.toIntValue(_clients.getAttribute("max-threads"), 20);
3046    
3047                    // Logger
3048                    String strLogger = hasAccess ? _clients.getAttribute("log") : null;
3049                    int logLevel = LogUtil.toIntType(_clients.getAttribute("log-level"), Log.LEVEL_ERROR);
3050                    LogAndSource log = ConfigWebUtil.getLogAndSource(configServer, config, strLogger, true, logLevel);
3051                    config.setRemoteClientLog(log);
3052    
3053                    // directory
3054                    Resource file = ConfigWebUtil.getFile(config.getRootDirectory(), _clients.getAttribute("directory"), "client-task", config.getConfigDir(), FileUtil.TYPE_DIR, config);
3055                    config.setRemoteClientDirectory(file);
3056    
3057                    Element[] clients;
3058                    Element client;
3059    
3060                    if (!hasAccess)
3061                            clients = new Element[0];
3062                    else
3063                            clients = getChildren(_clients, "remote-client");
3064                    java.util.List<RemoteClient> list = new ArrayList<RemoteClient>();
3065                    for (int i = 0; i < clients.length; i++) {
3066                            client = clients[i];
3067                            // type
3068                            String type = client.getAttribute("type");
3069                            if (StringUtil.isEmpty(type))
3070                                    type = "web";
3071                            // url
3072                            String url = client.getAttribute("url");
3073                            String label = client.getAttribute("label");
3074                            if (StringUtil.isEmpty(label))
3075                                    label = url;
3076                            String sUser = client.getAttribute("server-username");
3077                            String sPass = ConfigWebFactory.decrypt(client.getAttribute("server-password"));
3078                            String aPass = ConfigWebFactory.decrypt(client.getAttribute("admin-password"));
3079                            String aCode = ConfigWebFactory.decrypt(client.getAttribute("security-key"));
3080                            // if(aCode!=null && aCode.indexOf('-')!=-1)continue;
3081                            String usage = client.getAttribute("usage");
3082                            if (usage == null)
3083                                    usage = "";
3084    
3085                            String pUrl = client.getAttribute("proxy-server");
3086                            int pPort = Caster.toIntValue(client.getAttribute("proxy-port"), -1);
3087                            String pUser = client.getAttribute("proxy-username");
3088                            String pPass = ConfigWebFactory.decrypt(client.getAttribute("proxy-password"));
3089    
3090                            ProxyData pd = null;
3091                            if (!StringUtil.isEmpty(pUrl, true)) {
3092                                    pd = new ProxyDataImpl();
3093                                    pd.setServer(pUrl);
3094                                    if (!StringUtil.isEmpty(pUser)) {
3095                                            pd.setUsername(pUser);
3096                                            pd.setPassword(pPass);
3097                                    }
3098                                    if (pPort > 0)
3099                                            pd.setPort(pPort);
3100                            }
3101                            list.add(new RemoteClientImpl(label, type, url, sUser, sPass, aPass, pd, aCode, usage));
3102                    }
3103                    if (list.size() > 0)
3104                            config.setRemoteClients(list.toArray(new RemoteClient[list.size()]));
3105                    else
3106                            config.setRemoteClients(new RemoteClient[0]);
3107    
3108                    // init spooler engine
3109                    Resource dir = config.getRemoteClientDirectory();
3110                    if (dir != null && !dir.exists())
3111                            dir.mkdirs();
3112                    if (config.getSpoolerEngine() == null) {
3113                            config.setSpoolerEngine(new SpoolerEngineImpl(config, dir, "Remote Client Spooler", config.getRemoteClientLog(), maxThreads));
3114                    }
3115                    else {
3116                            SpoolerEngineImpl engine = (SpoolerEngineImpl) config.getSpoolerEngine();
3117                            engine.setConfig(config);
3118                            engine.setLog(config.getRemoteClientLog());
3119                            engine.setPersisDirectory(dir);
3120    
3121                    }
3122            }
3123    
3124            private static void loadSystem(ConfigServerImpl configServer, ConfigImpl config, Document doc) {
3125                    boolean hasAccess = ConfigWebUtil.hasAccess(config, SecurityManager.TYPE_SETTING);
3126                    Element sys = hasAccess ? getChildByName(doc.getDocumentElement(), "system") : null;
3127    
3128                    boolean hasCS = configServer != null;
3129    
3130                    String out = null, err = null;
3131                    if (sys != null) {
3132                            out = sys.getAttribute("out");
3133                            err = sys.getAttribute("err");
3134                    }
3135                    if (!StringUtil.isEmpty(out) && hasAccess) {
3136                            config.setOut(toPrintwriter(config, out, false));
3137                    }
3138                    else if (hasCS)
3139                            config.setOut(configServer.getOutWriter());
3140    
3141                    if (!StringUtil.isEmpty(err) && hasAccess) {
3142                            config.setErr(toPrintwriter(config, err, true));
3143                    }
3144                    else if (hasCS)
3145                            config.setErr(configServer.getErrWriter());
3146    
3147            }
3148    
3149            private static PrintWriter toPrintwriter(ConfigImpl config, String streamtype, boolean iserror) {
3150                    if (!StringUtil.isEmpty(streamtype)) {
3151                            streamtype = streamtype.trim();
3152    
3153                            if (streamtype.equalsIgnoreCase("null"))
3154                                    return new PrintWriter(DevNullOutputStream.DEV_NULL_OUTPUT_STREAM);
3155                            else if (StringUtil.startsWithIgnoreCase(streamtype, "class:")) {
3156                                    String classname = streamtype.substring(6);
3157                                    try {
3158                                            return (PrintWriter) ClassUtil.loadInstance(classname);
3159                                    }
3160                                    catch (Throwable t) {
3161                                            t.printStackTrace();
3162                                    }
3163                            }
3164                            else if (StringUtil.startsWithIgnoreCase(streamtype, "file:")) {
3165                                    String strRes = streamtype.substring(5);
3166                                    try {
3167                                            strRes = ConfigWebUtil.translateOldPath(strRes);
3168                                            Resource res = ConfigWebUtil.getFile(config, config.getConfigDir(), strRes, ResourceUtil.TYPE_FILE);
3169                                            if (res != null)
3170                                                    return new PrintWriter(res.getOutputStream(), true);
3171                                    }
3172                                    catch (Throwable t) {
3173                                            t.printStackTrace();
3174                                    }
3175                            }
3176    
3177                    }
3178                    if (iserror)
3179                            return SystemUtil.getPrintWriter(SystemUtil.ERR);
3180                    return SystemUtil.getPrintWriter(SystemUtil.OUT);
3181            }
3182    
3183            /**
3184             * @param configServer
3185             * @param config
3186             * @param doc
3187             */
3188            private static void loadCharset(ConfigServer configServer, ConfigImpl config, Document doc) {
3189    
3190                    boolean hasAccess = ConfigWebUtil.hasAccess(config, SecurityManager.TYPE_SETTING);
3191    
3192                    Element charset = hasAccess ? getChildByName(doc.getDocumentElement(), "charset") : null;
3193                    Element regional = hasAccess ? getChildByName(doc.getDocumentElement(), "regional") : null;
3194                    Element fileSystem = hasAccess ? getChildByName(doc.getDocumentElement(), "file-system") : null;
3195    
3196                    boolean hasCS = configServer != null;
3197    
3198                    // template
3199                    String template = null, fsCharset = null, fsEncoding = null;
3200                    if (charset != null)
3201                            template = charset.getAttribute("template-charset");
3202                    if (fileSystem != null)
3203                            fsCharset = fileSystem.getAttribute("charset"); // deprecated but
3204                                                                                                                            // still supported
3205                    if (fileSystem != null)
3206                            fsEncoding = fileSystem.getAttribute("encoding"); // deprecated but
3207                                                                                                                                    // still
3208                                                                                                                                    // supported
3209    
3210                    if (!StringUtil.isEmpty(template))
3211                            config.setTemplateCharset(template);
3212                    else if (!StringUtil.isEmpty(fsCharset))
3213                            config.setTemplateCharset(fsCharset);
3214                    else if (!StringUtil.isEmpty(fsEncoding))
3215                            config.setTemplateCharset(fsEncoding);
3216                    else if (hasCS)
3217                            config.setTemplateCharset(configServer.getTemplateCharset());
3218    
3219                    // web
3220                    String web = null, defaultEncoding = null;
3221                    if (charset != null)
3222                            web = charset.getAttribute("web-charset");
3223                    if (regional != null)
3224                            defaultEncoding = regional.getAttribute("default-encoding"); // deprecated
3225                                                                                                                                                            // but
3226                                                                                                                                                            // still
3227                                                                                                                                                            // supported
3228                    if (!StringUtil.isEmpty(web))
3229                            config.setWebCharset(web);
3230                    else if (!StringUtil.isEmpty(defaultEncoding))
3231                            config.setWebCharset(defaultEncoding);
3232                    else if (hasCS)
3233                            config.setWebCharset(configServer.getWebCharset());
3234    
3235                    // resource
3236                    String resource = null;
3237                    if (charset != null)
3238                            resource = charset.getAttribute("resource-charset");
3239                    if (!StringUtil.isEmpty(resource))
3240                            config.setResourceCharset(resource);
3241                    else if (hasCS)
3242                            config.setResourceCharset(configServer.getResourceCharset());
3243    
3244            }
3245    
3246            private static void loadThreadQueue(ConfigServer configServer, ConfigImpl config, Document doc) {
3247                    Element queue = getChildByName(doc.getDocumentElement(), "queue");
3248    
3249                    // Server
3250                    if (config instanceof ConfigServerImpl) {
3251                            int max = Caster.toIntValue(queue.getAttribute("max"), 100);
3252                            int timeout = Caster.toIntValue(queue.getAttribute("timeout"), 0);
3253                            ((ConfigServerImpl) config).setThreadQueue(new ThreadQueueImpl(max, timeout));
3254    
3255                    }
3256                    // Web
3257                    else {
3258                    }
3259            }
3260    
3261            /**
3262             * @param configServer
3263             * @param config
3264             * @param doc
3265             */
3266            private static void loadRegional(ConfigServer configServer, ConfigImpl config, Document doc) {
3267                    boolean hasAccess = ConfigWebUtil.hasAccess(config, SecurityManager.TYPE_SETTING);
3268    
3269                    Element regional = hasAccess ? getChildByName(doc.getDocumentElement(), "regional") : null;
3270                    boolean hasCS = configServer != null;
3271    
3272                    // timeZone
3273                    String strTimeZone = null;
3274                    if (regional != null)
3275                            strTimeZone = regional.getAttribute("timezone");
3276    
3277                    if (!StringUtil.isEmpty(strTimeZone))
3278                            config.setTimeZone(TimeZone.getTimeZone(strTimeZone));
3279                    else if (hasCS)
3280                            config.setTimeZone(configServer.getTimeZone());
3281                    else
3282                            config.setTimeZone(TimeZone.getDefault());
3283    
3284                    // timeserver
3285                    String strTimeServer = null;
3286                    Boolean useTimeServer = null;
3287                    if (regional != null) {
3288                            strTimeServer = regional.getAttribute("timeserver");
3289                            useTimeServer = Caster.toBoolean(regional.getAttribute("use-timeserver"), null);// 31
3290                    }
3291    
3292                    if (!StringUtil.isEmpty(strTimeServer))
3293                            config.setTimeServer(strTimeServer);
3294                    else if (hasCS)
3295                            config.setTimeServer(configServer.getTimeServer());
3296    
3297                    if (useTimeServer != null)
3298                            config.setUseTimeServer(useTimeServer.booleanValue());
3299                    else if (hasCS)
3300                            config.setUseTimeServer(((ConfigImpl) configServer).getUseTimeServer());
3301    
3302                    // locale
3303                    String strLocale = null;
3304                    if (regional != null)
3305                            strLocale = regional.getAttribute("locale");
3306    
3307                    if (!StringUtil.isEmpty(strLocale))
3308                            config.setLocale(strLocale);
3309                    else if (hasCS)
3310                            config.setLocale(configServer.getLocale());
3311                    else
3312                            config.setLocale(Locale.US);
3313    
3314            }
3315    
3316            private static void loadORM(ConfigServer configServer, ConfigImpl config, Document doc) throws IOException {
3317                    boolean hasAccess = ConfigWebUtil.hasAccess(config, SecurityManagerImpl.TYPE_ORM);
3318    
3319                    Element orm = hasAccess ? getChildByName(doc.getDocumentElement(), "orm") : null;
3320                    boolean hasCS = configServer != null;
3321    
3322                    // log
3323                    String strLogger = hasAccess ? orm.getAttribute("log") : null;
3324                    if (hasAccess && StringUtil.isEmpty(strLogger) && hasCS)
3325                            strLogger = ((ConfigServerImpl) configServer).getORMLogger().getSource();
3326                    else
3327                            strLogger = "{railo-config}/logs/orm.log";
3328    
3329                    int logLevel = hasAccess ? LogUtil.toIntType(orm.getAttribute("log-level"), -1) : -1;
3330                    if (logLevel == -1 && hasCS)
3331                            logLevel = ((ConfigServerImpl) configServer).getORMLogger().getLogLevel();
3332                    if (logLevel == -1)
3333                            logLevel = Log.LEVEL_ERROR;
3334    
3335                    config.setORMLogger(ConfigWebUtil.getLogAndSource(configServer, config, strLogger, hasAccess, logLevel));
3336    
3337                    // engine
3338                    String defaulrEngineClass = HibernateORMEngine.class.getName();// "railo.runtime.orm.hibernate.HibernateORMEngine";
3339    
3340                    // print.o("orm:"+defaulrEngineClass);
3341                    String strEngine = null;
3342                    if (orm != null)
3343                            strEngine = orm.getAttribute("engine-class");
3344                    if (StringUtil.isEmpty(strEngine, true))
3345                            strEngine = defaulrEngineClass;
3346    
3347                    // load class
3348                    Class<ORMEngine> clazz;
3349                    try {
3350                            clazz = ClassUtil.loadClass(strEngine);
3351                            // TODO check interface as well
3352                    }
3353                    catch (ClassException ce) {
3354                            ce.printStackTrace();
3355                            clazz = ClassUtil.loadClass(defaulrEngineClass, null);
3356                    }
3357                    config.setORMEngineClass(clazz);
3358    
3359                    // config
3360                    if (orm == null)
3361                            orm = doc.createElement("orm"); // this is just a dummy
3362                    ORMConfiguration def = hasCS ? ((ConfigServerImpl) configServer).getORMConfig() : null;
3363                    ORMConfiguration ormConfig = ORMConfigurationImpl.load(config, null, orm, config.getRootDirectory(), def);
3364                    config.setORMConfig(ormConfig);
3365    
3366            }
3367    
3368            /**
3369             * @param configServer
3370             * @param config
3371             * @param doc
3372             * @throws PageException
3373             * @throws IOException
3374             */
3375            private static void loadScope(ConfigServerImpl configServer, ConfigImpl config, Document doc, int mode) throws PageException {
3376                    boolean hasAccess = ConfigWebUtil.hasAccess(config, SecurityManager.TYPE_SETTING);
3377    
3378                    Element scope = getChildByName(doc.getDocumentElement(), "scope");
3379                    boolean hasCS = configServer != null;
3380    
3381                    // Cluster Scope
3382                    if (!hasCS) {
3383                            String strClass = scope.getAttribute("cluster-class");
3384                            if (hasAccess && !StringUtil.isEmpty(strClass)) {
3385                                    try {
3386                                            Class clazz = ClassUtil.loadClass(config.getClassLoader(), strClass);
3387                                            if (!Reflector.isInstaneOf(clazz, Cluster.class) && !Reflector.isInstaneOf(clazz, ClusterRemote.class))
3388                                                    throw new ApplicationException("class [" + clazz.getName() + "] does not implement interface [" + Cluster.class.getName() + "] or ["
3389                                                                    + ClusterRemote.class.getName() + "]");
3390    
3391                                            config.setClusterClass(clazz);
3392    
3393                                    }
3394                                    catch (ClassException e) {
3395                                            e.printStackTrace();
3396                                    }
3397    
3398                            }
3399                    }
3400                    // else if(hasCS)
3401                    // config.setClassClusterScope(configServer.getClassClusterScope());
3402    
3403                    // Local Mode
3404                    if (mode == ConfigImpl.MODE_STRICT) {
3405                            config.setLocalMode(Undefined.MODE_LOCAL_OR_ARGUMENTS_ALWAYS);
3406                    }
3407                    else {
3408                            String strLocalMode = scope.getAttribute("local-mode");
3409                            if (hasAccess && !StringUtil.isEmpty(strLocalMode)) {
3410                                    config.setLocalMode(strLocalMode);
3411                            }
3412                            else if (hasCS)
3413                                    config.setLocalMode(configServer.getLocalMode());
3414                    }
3415    
3416                    // Session-Type
3417                    String strSessionType = scope.getAttribute("session-type");
3418                    if (hasAccess && !StringUtil.isEmpty(strSessionType)) {
3419                            config.setSessionType(strSessionType);
3420                    }
3421                    else if (hasCS)
3422                            config.setSessionType(configServer.getSessionType());
3423    
3424                    // Cascading
3425                    if (mode == ConfigImpl.MODE_STRICT) {
3426                            config.setScopeCascadingType(Config.SCOPE_STRICT);
3427                    }
3428                    else {
3429                            String strScopeCascadingType = scope.getAttribute("cascading");
3430                            if (hasAccess && !StringUtil.isEmpty(strScopeCascadingType)) {
3431                                    config.setScopeCascadingType(strScopeCascadingType);
3432                            }
3433                            else if (hasCS)
3434                                    config.setScopeCascadingType(configServer.getScopeCascadingType());
3435                    }
3436    
3437                    // cascade-to-resultset
3438                    if (mode == ConfigImpl.MODE_STRICT) {
3439                            config.setAllowImplicidQueryCall(false);
3440                    }
3441                    else {
3442                            String strAllowImplicidQueryCall = scope.getAttribute("cascade-to-resultset");
3443                            if (hasAccess && !StringUtil.isEmpty(strAllowImplicidQueryCall)) {
3444                                    config.setAllowImplicidQueryCall(toBoolean(strAllowImplicidQueryCall, true));
3445                            }
3446                            else if (hasCS)
3447                                    config.setAllowImplicidQueryCall(configServer.allowImplicidQueryCall());
3448                    }
3449    
3450                    // Merge url and Form
3451                    String strMergeFormAndURL = scope.getAttribute("merge-url-form");
3452                    if (hasAccess && !StringUtil.isEmpty(strMergeFormAndURL)) {
3453                            config.setMergeFormAndURL(toBoolean(strMergeFormAndURL, false));
3454                    }
3455                    else if (hasCS)
3456                            config.setMergeFormAndURL(configServer.mergeFormAndURL());
3457    
3458                    // Client Timeout
3459                    String clientTimeout = scope.getAttribute("clienttimeout");
3460                    if (StringUtil.isEmpty(clientTimeout, true)) {
3461                            // deprecated
3462                            clientTimeout = scope.getAttribute("client-max-age");
3463                            int days = Caster.toIntValue(clientTimeout, -1);
3464                            if (days > 0)
3465                                    clientTimeout = days + ",0,0,0";
3466                            else
3467                                    clientTimeout = "";
3468                    }
3469                    if (hasAccess && !StringUtil.isEmpty(clientTimeout)) {
3470                            config.setClientTimeout(clientTimeout);
3471                    }
3472                    else if (hasCS)
3473                            config.setClientTimeout(configServer.getClientTimeout());
3474    
3475                    // Session Timeout
3476                    String sessionTimeout = scope.getAttribute("sessiontimeout");
3477                    if (hasAccess && !StringUtil.isEmpty(sessionTimeout)) {
3478                            config.setSessionTimeout(sessionTimeout);
3479                    }
3480                    else if (hasCS)
3481                            config.setSessionTimeout(configServer.getSessionTimeout());
3482    
3483                    // App Timeout
3484                    String appTimeout = scope.getAttribute("applicationtimeout");
3485                    if (hasAccess && !StringUtil.isEmpty(appTimeout)) {
3486                            config.setApplicationTimeout(appTimeout);
3487                    }
3488                    else if (hasCS)
3489                            config.setApplicationTimeout(configServer.getApplicationTimeout());
3490    
3491                    // Client Type
3492                    String strClientType = scope.getAttribute("clienttype");
3493                    if (hasAccess && !StringUtil.isEmpty(strClientType)) {
3494                            config.setClientType(strClientType);
3495                    }
3496                    else if (hasCS)
3497                            config.setClientType(configServer.getClientType());
3498    
3499                    // Client
3500                    Resource configDir = config.getConfigDir();
3501                    String strClientDirectory = scope.getAttribute("client-directory");
3502                    if (hasAccess && !StringUtil.isEmpty(strClientDirectory)) {
3503                            strClientDirectory = ConfigWebUtil.translateOldPath(strClientDirectory);
3504                            Resource res = ConfigWebUtil.getFile(configDir, strClientDirectory, "client-scope", configDir, FileUtil.TYPE_DIR, config);
3505                            config.setClientScopeDir(res);
3506                    }
3507                    else {
3508                            config.setClientScopeDir(configDir.getRealResource("client-scope"));
3509                    }
3510    
3511                    String strMax = scope.getAttribute("client-directory-max-size");
3512                    if (hasAccess && !StringUtil.isEmpty(strMax)) {
3513                            config.setClientScopeDirSize(ByteSizeParser.parseByteSizeDefinition(strMax, config.getClientScopeDirSize()));
3514                    }
3515                    else if (hasCS)
3516                            config.setClientScopeDirSize(configServer.getClientScopeDirSize());
3517    
3518                    // Session Management
3519                    String strSessionManagement = scope.getAttribute("sessionmanagement");
3520                    if (hasAccess && !StringUtil.isEmpty(strSessionManagement)) {
3521                            config.setSessionManagement(toBoolean(strSessionManagement, true));
3522                    }
3523                    else if (hasCS)
3524                            config.setSessionManagement(configServer.isSessionManagement());
3525    
3526                    // Client Management
3527                    String strClientManagement = scope.getAttribute("clientmanagement");
3528                    if (hasAccess && !StringUtil.isEmpty(strClientManagement)) {
3529                            config.setClientManagement(toBoolean(strClientManagement, false));
3530                    }
3531                    else if (hasCS)
3532                            config.setClientManagement(configServer.isClientManagement());
3533    
3534                    // Client Cookies
3535                    String strClientCookies = scope.getAttribute("setclientcookies");
3536                    if (hasAccess && !StringUtil.isEmpty(strClientCookies)) {
3537                            config.setClientCookies(toBoolean(strClientCookies, true));
3538                    }
3539                    else if (hasCS)
3540                            config.setClientCookies(configServer.isClientCookies());
3541    
3542                    // Domain Cookies
3543                    String strDomainCookies = scope.getAttribute("setdomaincookies");
3544                    if (hasAccess && !StringUtil.isEmpty(strDomainCookies)) {
3545                            config.setDomainCookies(toBoolean(strDomainCookies, false));
3546                    }
3547                    else if (hasCS)
3548                            config.setDomainCookies(configServer.isDomainCookies());
3549            }
3550    
3551            private static void loadJava(ConfigServerImpl configServer, ConfigImpl config, Document doc) {
3552                    boolean hasCS = configServer != null;
3553                    Element java = getChildByName(doc.getDocumentElement(), "java");
3554    
3555                    //
3556                    String strInspectTemplate = java.getAttribute("inspect-template");
3557                    if (!StringUtil.isEmpty(strInspectTemplate, true)) {
3558                            config.setInspectTemplate(ConfigWebUtil.inspectTemplate(strInspectTemplate, ConfigImpl.INSPECT_ONCE));
3559                    }
3560                    else if (hasCS) {
3561                            config.setInspectTemplate(configServer.getInspectTemplate());
3562                    }
3563    
3564                    //
3565                    String strCompileType = java.getAttribute("compile-type");
3566                    if (!StringUtil.isEmpty(strCompileType)) {
3567                            strCompileType = strCompileType.trim().toLowerCase();
3568                            if (strCompileType.equals("after-startup")) {
3569                                    config.setCompileType(Config.RECOMPILE_AFTER_STARTUP);
3570                            }
3571                            else if (strCompileType.equals("always")) {
3572                                    config.setCompileType(Config.RECOMPILE_ALWAYS);
3573                            }
3574                    }
3575                    else if (hasCS) {
3576                            config.setCompileType(configServer.getCompileType());
3577                    }
3578    
3579            }
3580    
3581            private static void loadConstants(ConfigServerImpl configServer, ConfigImpl config, Document doc) {
3582    
3583                    boolean hasCS = configServer != null;
3584                    Element constant = getChildByName(doc.getDocumentElement(), "constants");
3585    
3586                    // Constants
3587                    Element[] elConstants = getChildren(constant, "constant");
3588                    Struct sct = null;
3589                    if (hasCS) {
3590                            sct = configServer.getConstants();
3591                            if (sct != null)
3592                                    sct = (Struct) sct.duplicate(false);
3593                    }
3594                    if (sct == null)
3595                            sct = new StructImpl();
3596                    String name;
3597                    for (int i = 0; i < elConstants.length; i++) {
3598                            name = elConstants[i].getAttribute("name");
3599                            if (StringUtil.isEmpty(name))
3600                                    continue;
3601                            sct.setEL(KeyImpl.getInstance(name.trim()), elConstants[i].getAttribute("value"));
3602                    }
3603                    config.setConstants(sct);
3604            }
3605    
3606            private static void loadLogin(ConfigServerImpl configServer, ConfigImpl config, Document doc) {
3607                    // server context
3608                    if (config instanceof ConfigServer) {
3609                            Element login = getChildByName(doc.getDocumentElement(), "login");
3610                            boolean captcha = Caster.toBooleanValue(login.getAttribute("captcha"), false);
3611                            int delay = Caster.toIntValue(login.getAttribute("delay"), 0);
3612                            ConfigServerImpl cs = (ConfigServerImpl) config;
3613                            cs.setLoginDelay(delay);
3614                            cs.setLoginCaptcha(captcha);
3615                    }
3616            }
3617    
3618            /**
3619             * @param configServer
3620             * @param config
3621             * @param doc
3622             * @throws IOException
3623             */
3624            private static void loadMail(ConfigServerImpl configServer, ConfigImpl config, Document doc) throws IOException {
3625    
3626                    boolean hasAccess = ConfigWebUtil.hasAccess(config, SecurityManager.TYPE_MAIL);
3627    
3628                    boolean hasCS = configServer != null;
3629                    Element mail = getChildByName(doc.getDocumentElement(), "mail");
3630    
3631                    // Spool Interval
3632                    String strSpoolInterval = mail.getAttribute("spool-interval");
3633                    if (!StringUtil.isEmpty(strSpoolInterval) && hasAccess) {
3634                            config.setMailSpoolInterval(toInt(strSpoolInterval, 30));
3635                    }
3636                    else if (hasCS)
3637                            config.setMailSpoolInterval(configServer.getMailSpoolInterval());
3638    
3639                    String strEncoding = mail.getAttribute("default-encoding");
3640                    if (!StringUtil.isEmpty(strEncoding) && hasAccess)
3641                            config.setMailDefaultEncoding(strEncoding);
3642                    else if (hasCS)
3643                            config.setMailDefaultEncoding(configServer.getMailDefaultEncoding());
3644    
3645                    // Mail Logger
3646                    String strMailLogger = mail.getAttribute("log");
3647                    if (StringUtil.isEmpty(strMailLogger) && hasCS)
3648                            strMailLogger = configServer.getMailLogger().getSource();
3649    
3650                    int logLevel = LogUtil.toIntType(mail.getAttribute("log-level"), -1);
3651                    if (logLevel == -1 && hasCS)
3652                            logLevel = configServer.getMailLogger().getLogLevel();
3653                    if (logLevel == -1)
3654                            logLevel = Log.LEVEL_ERROR;
3655    
3656                    config.setMailLogger(ConfigWebUtil.getLogAndSource(configServer, config, strMailLogger, hasAccess, logLevel));
3657    
3658                    // Spool Enable
3659                    String strSpoolEnable = mail.getAttribute("spool-enable");
3660                    if (!StringUtil.isEmpty(strSpoolEnable) && hasAccess) {
3661                            config.setMailSpoolEnable(toBoolean(strSpoolEnable, false));
3662                    }
3663                    else if (hasCS)
3664                            config.setMailSpoolEnable(configServer.isMailSpoolEnable());
3665    
3666                    // Timeout
3667                    String strTimeout = mail.getAttribute("timeout");
3668                    if (!StringUtil.isEmpty(strTimeout) && hasAccess) {
3669                            config.setMailTimeout(toInt(strTimeout, 60));
3670                    }
3671                    else if (hasCS)
3672                            config.setMailTimeout(configServer.getMailTimeout());
3673    
3674                    // Servers
3675                    int index = 0;
3676                    Server[] servers = null;
3677                    Element[] elServers = getChildren(mail, "server");
3678                    if (hasCS) {
3679                            Server[] readOnlyServers = configServer.getMailServers();
3680                            servers = new Server[readOnlyServers.length + (hasAccess ? elServers.length : 0)];
3681                            for (int i = 0; i < readOnlyServers.length; i++) {
3682                                    servers[i] = readOnlyServers[index++].cloneReadOnly();
3683                            }
3684                    }
3685                    else {
3686                            servers = new Server[elServers.length];
3687                    }
3688                    if (hasAccess) {
3689                            for (int i = 0; i < elServers.length; i++) {
3690                                    Element el = elServers[i];
3691                                    if (el.getNodeName().equals("server"))
3692                                            servers[index++] = new ServerImpl(el.getAttribute("smtp"), toInt(el.getAttribute("port"), 25), el.getAttribute("username"),
3693                                                            decrypt(el.getAttribute("password")), toBoolean(el.getAttribute("tls"), false), toBoolean(el.getAttribute("ssl"), false));
3694    
3695                            }
3696                    }
3697                    config.setMailServers(servers);
3698            }
3699    
3700            private static void loadMonitors(ConfigServerImpl configServer, ConfigImpl config, Document doc) throws IOException {
3701                    if (configServer != null)
3702                            return;
3703    
3704                    configServer = (ConfigServerImpl) config;
3705    
3706                    Element parent = getChildByName(doc.getDocumentElement(), "monitoring");
3707                    boolean enabled = Caster.toBooleanValue(parent.getAttribute("enabled"), false);
3708                    configServer.setMonitoringEnabled(enabled);
3709    
3710                    Element[] children = getChildren(parent, "monitor");
3711                    java.util.List<IntervallMonitor> intervalls = new ArrayList<IntervallMonitor>();
3712                    java.util.List<RequestMonitor> requests = new ArrayList<RequestMonitor>();
3713                    java.util.List<MonitorTemp> actions = new ArrayList<MonitorTemp>();
3714                    String className, strType, name;
3715                    boolean log;
3716                    short type;
3717                    for (int i = 0; i < children.length; i++) {
3718                            Element el = children[i];
3719                            className = el.getAttribute("class");
3720                            strType = el.getAttribute("type");
3721                            name = el.getAttribute("name");
3722                            log = Caster.toBooleanValue(el.getAttribute("log"), true);
3723    
3724                            if ("request".equalsIgnoreCase(strType))
3725                                    type = IntervallMonitor.TYPE_REQUEST;
3726                            else if ("action".equalsIgnoreCase(strType))
3727                                    type = 4;// FUTURE Monitor.TYPE_ACTION;
3728                            else
3729                                    type = IntervallMonitor.TYPE_INTERVALL;
3730    
3731                            if (!StringUtil.isEmpty(className) && !StringUtil.isEmpty(name)) {
3732                                    name = name.trim();
3733                                    try {
3734                                            Class clazz = ClassUtil.loadClass(config.getClassLoader(), className);
3735                                            Object obj;
3736                                            ConstructorInstance constr = Reflector.getConstructorInstance(clazz, new Object[] { configServer }, null);
3737                                            if (constr != null)
3738                                                    obj = constr.invoke();
3739                                            else
3740                                                    obj = clazz.newInstance();
3741    
3742                                            if (type == IntervallMonitor.TYPE_INTERVALL) {
3743                                                    IntervallMonitor m = obj instanceof IntervallMonitor ? (IntervallMonitor) obj : new IntervallMonitorWrap(obj);
3744                                                    m.init(configServer, name, log);
3745                                                    intervalls.add(m);
3746                                            }
3747                                            else if (type == 4) {// FUTURE Monitor.TYPE_ACTION;
3748                                                    actions.add(new MonitorTemp(obj, name, log));
3749                                            }
3750                                            else {
3751                                                    RequestMonitor m = obj instanceof RequestMonitor ? (RequestMonitor) obj : new RequestMonitorWrap(obj);
3752                                                    m.init(configServer, name, log);
3753                                                    requests.add(m);
3754                                            }
3755                                    }
3756                                    catch (Throwable t) {
3757                                            SystemOut.printDate(config.getErrWriter(), t.getMessage());
3758                                    }
3759                            }
3760    
3761                    }
3762                    configServer.setRequestMonitors(requests.toArray(new RequestMonitor[requests.size()]));
3763                    configServer.setIntervallMonitors(intervalls.toArray(new IntervallMonitor[intervalls.size()]));
3764                    ActionMonitorCollector actionMonitorCollector = ActionMonitorFatory.getActionMonitorCollector(configServer, actions.toArray(new MonitorTemp[actions.size()]));
3765                    configServer.setActionMonitorCollector(actionMonitorCollector);
3766    
3767                    ((CFMLEngineImpl) configServer.getCFMLEngine()).touchMonitor(configServer);
3768            }
3769    
3770            /**
3771             * @param configServer
3772             * @param config
3773             * @param doc
3774             * @throws PageException
3775             */
3776            private static void loadSearch(ConfigServer configServer, ConfigImpl config, Document doc) throws PageException {
3777                    if (config instanceof ConfigServer)
3778                            return;
3779    
3780                    // ServletContext sc=config.getServletContext();
3781                    Resource configDir = config.getConfigDir();
3782    
3783                    Element search = getChildByName(doc.getDocumentElement(), "search");
3784    
3785                    String strEngineClass = search.getAttribute("engine-class");
3786                    SearchEngine se = null;
3787                    Object o = ClassUtil.loadInstance(strEngineClass, (Object) null);
3788                    if (o instanceof SearchEngine)
3789                            se = (SearchEngine) o;
3790    
3791                    if (se == null)
3792                            se = new railo.runtime.search.lucene2.LuceneSearchEngine();
3793    
3794                    try {
3795                            // Logger
3796                            String strLogger = search.getAttribute("log");
3797                            int logLevel = LogUtil.toIntType(search.getAttribute("log-level"), Log.LEVEL_ERROR);
3798                            LogAndSource log = ConfigWebUtil.getLogAndSource(configServer, config, strLogger, true, logLevel);
3799    
3800                            // Init
3801                            se.init(config, ConfigWebUtil.getFile(configDir, ConfigWebUtil.translateOldPath(search.getAttribute("directory")), "search", configDir, FileUtil.TYPE_DIR, config), log);
3802                    }
3803                    catch (Exception e) {
3804                            throw Caster.toPageException(e);
3805                    }
3806    
3807                    config.setSearchEngine(se);
3808            }
3809    
3810            /**
3811             * @param configServer
3812             * @param config
3813             * @param doc
3814             * @param isEventGatewayContext
3815             * @throws IOException
3816             * @throws PageException
3817             */
3818            private static void loadScheduler(ConfigServer configServer, ConfigImpl config, Document doc) throws PageException, IOException {
3819                    if (config instanceof ConfigServer)
3820                            return;
3821    
3822                    Resource configDir = config.getConfigDir();
3823                    Element scheduler = getChildByName(doc.getDocumentElement(), "scheduler");
3824    
3825                    // Logger
3826                    String strLogger = scheduler.getAttribute("log");
3827                    int logLevel = LogUtil.toIntType(scheduler.getAttribute("log-level"), Log.LEVEL_INFO);
3828                    LogAndSource log = ConfigWebUtil.getLogAndSource(configServer, config, strLogger, true, logLevel);
3829    
3830                    // set scheduler
3831                    Resource file = ConfigWebUtil.getFile(config.getRootDirectory(), scheduler.getAttribute("directory"), "scheduler", configDir, FileUtil.TYPE_DIR, config);
3832                    config.setScheduler(configServer.getCFMLEngine(), file, log);
3833            }
3834    
3835            /**
3836             * @param configServer
3837             * @param config
3838             * @param doc
3839             */
3840            private static void loadDebug(ConfigServerImpl configServer, ConfigImpl config, Document doc) {
3841                    boolean hasCS = configServer != null;
3842                    Element debugging = getChildByName(doc.getDocumentElement(), "debugging");
3843                    boolean hasAccess = ConfigWebUtil.hasAccess(config, SecurityManager.TYPE_DEBUGGING);
3844    
3845                    // Entries
3846                    Element[] entries = getChildren(debugging, "debug-entry");
3847                    Map<String, DebugEntry> list = new HashMap<String, DebugEntry>();
3848                    if (hasCS) {
3849                            DebugEntry[] _entries = ((ConfigImpl) configServer).getDebugEntries();
3850                            for (int i = 0; i < _entries.length; i++) {
3851                                    list.put(_entries[i].getId(), _entries[i].duplicate(true));
3852                            }
3853                    }
3854                    Element e;
3855                    String id;
3856                    for (int i = 0; i < entries.length; i++) {
3857                            e = entries[i];
3858                            id = e.getAttribute("id");
3859                            try {
3860                                    list.put(id, new DebugEntry(id, e.getAttribute("type"), e.getAttribute("iprange"), e.getAttribute("label"), e.getAttribute("path"), e.getAttribute("fullname"),
3861                                                    toStruct(e.getAttribute("custom"))));
3862                            }
3863                            catch (IOException ioe) {
3864                            }
3865                    }
3866                    config.setDebugEntries(list.values().toArray(new DebugEntry[list.size()]));
3867    
3868                    // debug
3869                    String strDebug = debugging.getAttribute("debug");
3870                    if (hasAccess && !StringUtil.isEmpty(strDebug)) {
3871                            config.setDebug(toBoolean(strDebug, false) ? ConfigImpl.CLIENT_BOOLEAN_TRUE : ConfigImpl.CLIENT_BOOLEAN_FALSE);
3872                    }
3873                    else if (hasCS)
3874                            config.setDebug(configServer.debug() ? ConfigImpl.SERVER_BOOLEAN_TRUE : ConfigImpl.SERVER_BOOLEAN_FALSE);
3875    
3876                    // debug-log-output
3877                    String strDLO = debugging.getAttribute("debug-log-output");
3878                    if (hasAccess && !StringUtil.isEmpty(strDLO)) {
3879                            config.setDebugLogOutput(toBoolean(strDLO, false) ? ConfigImpl.CLIENT_BOOLEAN_TRUE : ConfigImpl.CLIENT_BOOLEAN_FALSE);
3880                    }
3881                    else if (hasCS)
3882                            config.setDebugLogOutput(configServer.debugLogOutput() ? ConfigImpl.SERVER_BOOLEAN_TRUE : ConfigImpl.SERVER_BOOLEAN_FALSE);
3883    
3884                    // debug options
3885                    int options = 0;
3886                    String str = debugging.getAttribute("database");
3887                    if (hasAccess && !StringUtil.isEmpty(str)) {
3888                            if (toBoolean(str, false))
3889                                    options += ConfigImpl.DEBUG_DATABASE;
3890                    }
3891                    else if (hasCS && configServer.hasDebugOptions(ConfigImpl.DEBUG_DATABASE))
3892                            options += ConfigImpl.DEBUG_DATABASE;
3893    
3894                    str = debugging.getAttribute("exception");
3895                    if (hasAccess && !StringUtil.isEmpty(str)) {
3896                            if (toBoolean(str, false))
3897                                    options += ConfigImpl.DEBUG_EXCEPTION;
3898                    }
3899                    else if (hasCS && configServer.hasDebugOptions(ConfigImpl.DEBUG_EXCEPTION))
3900                            options += ConfigImpl.DEBUG_EXCEPTION;
3901    
3902                    str = debugging.getAttribute("tracing");
3903                    if (hasAccess && !StringUtil.isEmpty(str)) {
3904                            if (toBoolean(str, false))
3905                                    options += ConfigImpl.DEBUG_TRACING;
3906                    }
3907                    else if (hasCS && configServer.hasDebugOptions(ConfigImpl.DEBUG_TRACING))
3908                            options += ConfigImpl.DEBUG_TRACING;
3909    
3910                    str = debugging.getAttribute("timer");
3911                    if (hasAccess && !StringUtil.isEmpty(str)) {
3912                            if (toBoolean(str, false))
3913                                    options += ConfigImpl.DEBUG_TIMER;
3914                    }
3915                    else if (hasCS && configServer.hasDebugOptions(ConfigImpl.DEBUG_TIMER))
3916                            options += ConfigImpl.DEBUG_TIMER;
3917    
3918                    str = debugging.getAttribute("implicit-access");
3919                    if (hasAccess && !StringUtil.isEmpty(str)) {
3920                            if (toBoolean(str, false))
3921                                    options += ConfigImpl.DEBUG_IMPLICIT_ACCESS;
3922                    }
3923                    else if (hasCS && configServer.hasDebugOptions(ConfigImpl.DEBUG_IMPLICIT_ACCESS))
3924                            options += ConfigImpl.DEBUG_IMPLICIT_ACCESS;
3925    
3926                    str = debugging.getAttribute("query-usage");
3927                    if (StringUtil.isEmpty(str))
3928                            str = debugging.getAttribute("show-query-usage");
3929                    if (hasAccess && !StringUtil.isEmpty(str)) {
3930                            if (toBoolean(str, false))
3931                                    options += ConfigImpl.DEBUG_QUERY_USAGE;
3932                    }
3933                    else if (hasCS && configServer.hasDebugOptions(ConfigImpl.DEBUG_QUERY_USAGE))
3934                            options += ConfigImpl.DEBUG_QUERY_USAGE;
3935    
3936                    // max records logged
3937                    String strMax = debugging.getAttribute("max-records-logged");
3938                    if (hasAccess && !StringUtil.isEmpty(strMax)) {
3939                            config.setDebugMaxRecordsLogged(toInt(strMax, 10));
3940                    }
3941                    else if (hasCS)
3942                            config.setDebugMaxRecordsLogged(configServer.getDebugMaxRecordsLogged());
3943    
3944                    config.setDebugOptions(options);
3945            }
3946    
3947            /**
3948             * @param configServer
3949             * @param config
3950             * @param doc
3951             */
3952            private static void loadCFX(ConfigServerImpl configServer, ConfigImpl config, Document doc) {
3953    
3954                    boolean hasAccess = ConfigWebUtil.hasAccess(config, SecurityManager.TYPE_CFX_SETTING);
3955    
3956                    HashTable map = new HashTable();
3957                    if (configServer != null) {
3958                            try {
3959                                    if (configServer.getCFXTagPool() != null) {
3960                                            Map classes = configServer.getCFXTagPool().getClasses();
3961                                            Iterator it = classes.keySet().iterator();
3962                                            while (it.hasNext()) {
3963                                                    Object key = it.next();
3964                                                    map.put(key, ((CFXTagClass) classes.get(key)).cloneReadOnly());
3965                                            }
3966                                    }
3967                            }
3968                            catch (SecurityException e) {
3969                            }
3970                    }
3971    
3972                    if (hasAccess) {
3973                            if (configServer == null) {
3974                                    System.setProperty("cfx.bin.path", config.getConfigDir().getRealResource("bin").getAbsolutePath());
3975                            }
3976    
3977                            // Java CFX Tags
3978                            Element cfxTagsParent = getChildByName(doc.getDocumentElement(), "ext-tags", false, true);
3979                            if (cfxTagsParent == null)
3980                                    cfxTagsParent = getChildByName(doc.getDocumentElement(), "cfx-tags", false, true);
3981                            if (cfxTagsParent == null)
3982                                    cfxTagsParent = getChildByName(doc.getDocumentElement(), "ext-tags");
3983    
3984                            boolean oldStyle = cfxTagsParent.getNodeName().equals("cfx-tags");
3985    
3986                            Element[] cfxTags = oldStyle ? getChildren(cfxTagsParent, "cfx-tag") : getChildren(cfxTagsParent, "ext-tag");
3987                            for (int i = 0; i < cfxTags.length; i++) {
3988                                    String type = cfxTags[i].getAttribute("type");
3989                                    if (type != null) {
3990                                            // Java CFX Tags
3991                                            if (type.equalsIgnoreCase("java")) {
3992                                                    String name = cfxTags[i].getAttribute("name");
3993                                                    String clazz = cfxTags[i].getAttribute("class");
3994                                                    if (!StringUtil.isEmpty(name) && !StringUtil.isEmpty(clazz)) {
3995                                                            map.put(name.toLowerCase(), new JavaCFXTagClass(name, clazz));
3996                                                    }
3997                                            }
3998                                            // C++ CFX Tags
3999                                            else if (type.equalsIgnoreCase("cpp")) {
4000                                                    String name = cfxTags[i].getAttribute("name");
4001                                                    String serverLibrary = cfxTags[i].getAttribute("server-library");
4002                                                    String procedure = cfxTags[i].getAttribute("procedure");
4003                                                    boolean keepAlive = Caster.toBooleanValue(cfxTags[i].getAttribute("keep-alive"), false);
4004    
4005                                                    if (!StringUtil.isEmpty(name) && !StringUtil.isEmpty(serverLibrary) && !StringUtil.isEmpty(procedure)) {
4006                                                            map.put(name.toLowerCase(), new CPPCFXTagClass(name, serverLibrary, procedure, keepAlive));
4007                                                    }
4008                                            }
4009                                    }
4010                            }
4011    
4012                    }
4013                    config.setCFXTagPool(map);
4014            }
4015    
4016            private static void loadExtensions(ConfigServerImpl configServer, ConfigImpl config, Document doc) {
4017    
4018                    Element xmlExtParent = getChildByName(doc.getDocumentElement(), "extensions");
4019    
4020                    String strEnabled = xmlExtParent.getAttribute("enabled");
4021                    if (!StringUtil.isEmpty(strEnabled)) {
4022                            config.setExtensionEnabled(Caster.toBooleanValue(strEnabled, false));
4023                    }
4024    
4025                    // providers
4026                    Element[] xmlProviders = getChildren(xmlExtParent, "provider");
4027                    String provider;
4028                    Map list = new HashMap();
4029    
4030                    for (int i = 0; i < ConfigImpl.RAILO_EXTENSION_PROVIDERS.length; i++) {
4031                            list.put(ConfigImpl.RAILO_EXTENSION_PROVIDERS[i], "");
4032                    }
4033    
4034                    for (int i = 0; i < xmlProviders.length; i++) {
4035                            provider = xmlProviders[i].getAttribute("url");
4036                            if (!StringUtil.isEmpty(provider, true) && !"http://www.railo-technologies.com/ExtensionProvider.cfc".equals(provider)
4037                                            && !"http://www.railo.ch/ExtensionProvider.cfc".equals(provider)) {
4038                                    list.put(new ExtensionProviderImpl(provider.trim(), false), "");
4039                            }
4040                    }
4041                    config.setExtensionProviders((ExtensionProvider[]) list.keySet().toArray(new ExtensionProvider[list.size()]));
4042    
4043                    // extensions
4044                    Element[] xmlExtensions = getChildren(xmlExtParent, "extension");
4045                    Extension[] extensions = new Extension[xmlExtensions.length];
4046                    Element xmlExtension;
4047                    for (int i = 0; i < xmlExtensions.length; i++) {
4048                            xmlExtension = xmlExtensions[i];
4049                            extensions[i] = new ExtensionImpl(xmlExtension.getAttribute("config"), xmlExtension.getAttribute("id"), xmlExtension.getAttribute("provider"),
4050                                            xmlExtension.getAttribute("version"),
4051    
4052                                            xmlExtension.getAttribute("name"), xmlExtension.getAttribute("label"), xmlExtension.getAttribute("description"), xmlExtension.getAttribute("category"),
4053                                            xmlExtension.getAttribute("image"), xmlExtension.getAttribute("author"), xmlExtension.getAttribute("codename"), xmlExtension.getAttribute("video"),
4054                                            xmlExtension.getAttribute("support"), xmlExtension.getAttribute("documentation"), xmlExtension.getAttribute("forum"), xmlExtension.getAttribute("mailinglist"),
4055                                            xmlExtension.getAttribute("network"), DateCaster.toDateAdvanced(xmlExtension.getAttribute("created"), null, null), xmlExtension.getAttribute("type"));
4056                    }
4057                    config.setExtensions(extensions);
4058    
4059            }
4060    
4061            /**
4062             * @param configServer
4063             * @param config
4064             * @param doc
4065             * @throws IOException
4066             */
4067            private static void loadComponent(ConfigServer configServer, ConfigImpl config, Document doc, int mode) {
4068                    Element component = getChildByName(doc.getDocumentElement(), "component");
4069                    boolean hasAccess = ConfigWebUtil.hasAccess(config, SecurityManager.TYPE_SETTING);
4070                    boolean hasSet = false;
4071                    boolean hasCS = configServer != null;
4072    
4073                    // String virtual="/component/";
4074    
4075                    if (component != null && hasAccess) {
4076    
4077                            // component-default-import
4078                            String strCDI = component.getAttribute("component-default-import");
4079                            if (StringUtil.isEmpty(strCDI, true) && configServer != null) {
4080                                    strCDI = ((ConfigServerImpl) configServer).getComponentDefaultImport().toString();
4081                            }
4082                            if (!StringUtil.isEmpty(strCDI, true))
4083                                    config.setComponentDefaultImport(strCDI);
4084    
4085                            // Base
4086                            String strBase = component.getAttribute("base");
4087                            if (StringUtil.isEmpty(strBase, true) && configServer != null) {
4088                                    strBase = configServer.getBaseComponentTemplate();
4089                            }
4090                            config.setBaseComponentTemplate(strBase);
4091    
4092                            // deep search
4093                            if (mode == ConfigImpl.MODE_STRICT) {
4094                                    config.setDoComponentDeepSearch(false);
4095                            }
4096                            else {
4097                                    String strDeepSearch = component.getAttribute("deep-search");
4098                                    if (!StringUtil.isEmpty(strDeepSearch)) {
4099                                            config.setDoComponentDeepSearch(Caster.toBooleanValue(strDeepSearch.trim(), false));
4100                                    }
4101                                    else if (hasCS) {
4102                                            config.setDoComponentDeepSearch(((ConfigServerImpl) configServer).doComponentDeepSearch());
4103                                    }
4104                            }
4105    
4106                            // Dump-Template
4107                            String strDumpRemplate = component.getAttribute("dump-template");
4108                            if ((strDumpRemplate == null || strDumpRemplate.trim().length() == 0) && configServer != null) {
4109                                    strDumpRemplate = configServer.getComponentDumpTemplate();
4110                            }
4111                            config.setComponentDumpTemplate(strDumpRemplate);
4112    
4113                            // data-member-default-access
4114                            if (mode == ConfigImpl.MODE_STRICT) {
4115                                    config.setComponentDataMemberDefaultAccess(Component.ACCESS_PRIVATE);
4116                            }
4117                            else {
4118                                    String strDmda = component.getAttribute("data-member-default-access");
4119                                    if (strDmda != null && strDmda.trim().length() > 0) {
4120                                            strDmda = strDmda.toLowerCase().trim();
4121                                            if (strDmda.equals("remote"))
4122                                                    config.setComponentDataMemberDefaultAccess(Component.ACCESS_REMOTE);
4123                                            else if (strDmda.equals("public"))
4124                                                    config.setComponentDataMemberDefaultAccess(Component.ACCESS_PUBLIC);
4125                                            else if (strDmda.equals("package"))
4126                                                    config.setComponentDataMemberDefaultAccess(Component.ACCESS_PACKAGE);
4127                                            else if (strDmda.equals("private"))
4128                                                    config.setComponentDataMemberDefaultAccess(Component.ACCESS_PRIVATE);
4129                                    }
4130                                    else if (configServer != null) {
4131                                            config.setComponentDataMemberDefaultAccess(configServer.getComponentDataMemberDefaultAccess());
4132                                    }
4133                            }
4134    
4135                            // trigger-properties
4136                            if (mode == ConfigImpl.MODE_STRICT) {
4137                                    config.setTriggerComponentDataMember(true);
4138                            }
4139                            else {
4140                                    Boolean tp = Caster.toBoolean(component.getAttribute("trigger-data-member"), null);
4141                                    if (tp != null)
4142                                            config.setTriggerComponentDataMember(tp.booleanValue());
4143                                    else if (configServer != null) {
4144                                            config.setTriggerComponentDataMember(configServer.getTriggerComponentDataMember());
4145                                    }
4146                            }
4147    
4148                            // local search
4149                            if (mode == ConfigImpl.MODE_STRICT) {
4150                                    config.setComponentLocalSearch(false);
4151                            }
4152                            else {
4153                                    Boolean ls = Caster.toBoolean(component.getAttribute("local-search"), null);
4154                                    if (ls != null)
4155                                            config.setComponentLocalSearch(ls.booleanValue());
4156                                    else if (configServer != null) {
4157                                            config.setComponentLocalSearch(((ConfigServerImpl) configServer).getComponentLocalSearch());
4158                                    }
4159                            }
4160    
4161                            // use cache path
4162                            Boolean ucp = Caster.toBoolean(component.getAttribute("use-cache-path"), null);
4163                            if (ucp != null)
4164                                    config.setUseComponentPathCache(ucp.booleanValue());
4165                            else if (configServer != null) {
4166                                    config.setUseComponentPathCache(((ConfigServerImpl) configServer).useComponentPathCache());
4167                            }
4168    
4169                            // use component shadow
4170                            if (mode == ConfigImpl.MODE_STRICT) {
4171                                    config.setUseComponentShadow(false);
4172                            }
4173                            else {
4174                                    Boolean ucs = Caster.toBoolean(component.getAttribute("use-shadow"), null);
4175                                    if (ucs != null)
4176                                            config.setUseComponentShadow(ucs.booleanValue());
4177                                    else if (configServer != null) {
4178                                            config.setUseComponentShadow(configServer.useComponentShadow());
4179                                    }
4180                            }
4181    
4182                    }
4183                    else if (configServer != null) {
4184                            config.setBaseComponentTemplate(configServer.getBaseComponentTemplate());
4185                            config.setComponentDumpTemplate(configServer.getComponentDumpTemplate());
4186                            if (mode == ConfigImpl.MODE_STRICT) {
4187                                    config.setComponentDataMemberDefaultAccess(Component.ACCESS_PRIVATE);
4188                                    config.setTriggerComponentDataMember(true);
4189                            }
4190                            else {
4191                                    config.setComponentDataMemberDefaultAccess(configServer.getComponentDataMemberDefaultAccess());
4192                                    config.setTriggerComponentDataMember(configServer.getTriggerComponentDataMember());
4193                            }
4194                    }
4195    
4196                    if (mode == ConfigImpl.MODE_STRICT) {
4197                            config.setDoComponentDeepSearch(false);
4198                            config.setComponentDataMemberDefaultAccess(Component.ACCESS_PRIVATE);
4199                            config.setTriggerComponentDataMember(true);
4200                            config.setComponentLocalSearch(false);
4201                            config.setUseComponentShadow(false);
4202    
4203                    }
4204    
4205                    // Web Mapping
4206    
4207                    Element[] cMappings = getChildren(component, "mapping");
4208                    hasSet = false;
4209                    Mapping[] mappings = null;
4210                    if (hasAccess && cMappings.length > 0) {
4211                            mappings = new Mapping[cMappings.length];
4212                            for (int i = 0; i < cMappings.length; i++) {
4213                                    Element cMapping = cMappings[i];
4214                                    String physical = cMapping.getAttribute("physical");
4215                                    String archive = cMapping.getAttribute("archive");
4216                                    boolean readonly = toBoolean(cMapping.getAttribute("readonly"), false);
4217                                    boolean hidden = toBoolean(cMapping.getAttribute("hidden"), false);
4218                                    //boolean trusted = toBoolean(cMapping.getAttribute("trusted"), false);
4219                                    short inspTemp = inspectTemplate(cMapping);
4220                                    String virtual = ConfigWebAdmin.createVirtual(cMapping);
4221    
4222                                    int clMaxEl = toInt(cMapping.getAttribute("classloader-max-elements"), 100);
4223    
4224                                    String primary = cMapping.getAttribute("primary");
4225    
4226                                    boolean physicalFirst = archive == null || !primary.equalsIgnoreCase("archive");
4227                                    hasSet = true;
4228                                    mappings[i] = new MappingImpl(config, virtual, physical, archive, inspTemp, physicalFirst, hidden, readonly, true, false, true, null, clMaxEl);
4229                            }
4230    
4231                            config.setComponentMappings(mappings);
4232    
4233                    }
4234    
4235                    // Server Mapping
4236                    if (hasCS) {
4237                            Mapping[] originals = ((ConfigServerImpl) configServer).getComponentMappings();
4238                            Mapping[] clones = new Mapping[originals.length];
4239                            LinkedHashMap map = new LinkedHashMap();
4240                            Mapping m;
4241                            for (int i = 0; i < clones.length; i++) {
4242                                    m = ((MappingImpl) originals[i]).cloneReadOnly(config);
4243                                    map.put(toKey(m), m);
4244                                    // clones[i]=((MappingImpl)m[i]).cloneReadOnly(config);
4245                            }
4246    
4247                            if (mappings != null) {
4248                                    for (int i = 0; i < mappings.length; i++) {
4249                                            m = mappings[i];
4250                                            map.put(toKey(m), m);
4251                                    }
4252                            }
4253                            if (originals.length > 0) {
4254                                    clones = new Mapping[map.size()];
4255                                    Iterator it = map.entrySet().iterator();
4256                                    Map.Entry entry;
4257                                    int index = 0;
4258                                    while (it.hasNext()) {
4259                                            entry = (Entry) it.next();
4260                                            clones[index++] = (Mapping) entry.getValue();
4261                                            // print.out("c:"+clones[index-1]);
4262                                    }
4263                                    hasSet = true;
4264                                    // print.err("set:"+clones.length);
4265    
4266                                    config.setComponentMappings(clones);
4267                            }
4268                    }
4269    
4270                    if (!hasSet) {
4271                            MappingImpl m = new MappingImpl(config, "/default", "{railo-web}/components/", null, ConfigImpl.INSPECT_UNDEFINED, true, false, false, true, false, true, null);
4272                            config.setComponentMappings(new Mapping[] { m.cloneReadOnly(config) });
4273                    }
4274    
4275            }
4276    
4277            private static void loadProxy(ConfigServerImpl configServer, ConfigImpl config, Document doc) {
4278    
4279                    boolean hasCS = configServer != null;
4280                    boolean hasAccess = ConfigWebUtil.hasAccess(config, SecurityManager.TYPE_SETTING);
4281                    Element proxy = getChildByName(doc.getDocumentElement(), "proxy");
4282    
4283                    // server
4284    
4285                    // proxy enabled
4286                    // String enabled=proxy.getAttribute("enabled");
4287                    // if(hasAccess && !StringUtil.isEmpty(enabled))
4288                    // config.setProxyEnable(toBoolean(enabled, false));
4289                    // else if(hasCS) config.setProxyEnable(configServer.isProxyEnable());
4290    
4291                    // proxy server
4292                    String server = proxy.getAttribute("server");
4293                    String username = proxy.getAttribute("username");
4294                    String password = proxy.getAttribute("password");
4295                    int port = toInt(proxy.getAttribute("port"), -1);
4296    
4297                    if (hasAccess && !StringUtil.isEmpty(server)) {
4298                            config.setProxyData(ProxyDataImpl.getInstance(server, port, username, password));
4299                    }
4300                    else if (hasCS)
4301                            config.setProxyData(configServer.getProxyData());
4302            }
4303    
4304            private static void loadError(ConfigServerImpl configServer, ConfigImpl config, Document doc) {
4305                    Element error = getChildByName(doc.getDocumentElement(), "error");
4306                    boolean hasCS = configServer != null;
4307                    boolean hasAccess = ConfigWebUtil.hasAccess(config, SecurityManager.TYPE_DEBUGGING);
4308    
4309                    // error template
4310                    String template = error.getAttribute("template");
4311    
4312                    // 500
4313                    String template500 = error.getAttribute("template-500");
4314                    if (StringUtil.isEmpty(template500))
4315                            template500 = error.getAttribute("template500");
4316                    if (StringUtil.isEmpty(template500))
4317                            template500 = error.getAttribute("500");
4318                    if (StringUtil.isEmpty(template500))
4319                            template500 = template;
4320                    if (hasAccess && !StringUtil.isEmpty(template500)) {
4321                            config.setErrorTemplate(500, template500);
4322                    }
4323                    else if (hasCS)
4324                            config.setErrorTemplate(500, configServer.getErrorTemplate(500));
4325                    else
4326                            config.setErrorTemplate(500, "/railo-context/templates/error/error.cfm");
4327    
4328                    // 404
4329                    String template404 = error.getAttribute("template-404");
4330                    if (StringUtil.isEmpty(template404))
4331                            template404 = error.getAttribute("template404");
4332                    if (StringUtil.isEmpty(template404))
4333                            template404 = error.getAttribute("404");
4334                    if (StringUtil.isEmpty(template404))
4335                            template404 = template;
4336                    if (hasAccess && !StringUtil.isEmpty(template404)) {
4337                            config.setErrorTemplate(404, template404);
4338                    }
4339                    else if (hasCS)
4340                            config.setErrorTemplate(404, configServer.getErrorTemplate(404));
4341                    else
4342                            config.setErrorTemplate(404, "/railo-context/templates/error/error.cfm");
4343    
4344                    // status code
4345                    String strStausCode = error.getAttribute("status-code");
4346                    if (StringUtil.isEmpty(strStausCode))
4347                            strStausCode = error.getAttribute("statusCode");
4348                    if (StringUtil.isEmpty(strStausCode))
4349                            strStausCode = error.getAttribute("status");
4350    
4351                    if (!StringUtil.isEmpty(strStausCode) && hasAccess) {
4352                            config.setErrorStatusCode(toBoolean(strStausCode, true));
4353                    }
4354                    else if (hasCS)
4355                            config.setErrorStatusCode(configServer.getErrorStatusCode());
4356    
4357            }
4358    
4359            private static void loadCompiler(ConfigServerImpl configServer, ConfigImpl config, Document doc, int mode) {
4360                    boolean hasCS = configServer != null;
4361    
4362                    Element compiler = getChildByName(doc.getDocumentElement(), "compiler");
4363    
4364                    // supress WS between cffunction and cfargument
4365                    if (mode == ConfigImpl.MODE_STRICT) {
4366                            config.setSupressWSBeforeArg(true);
4367                    }
4368                    else {
4369                            String supress = compiler.getAttribute("supress-ws-before-arg");
4370                            if (!StringUtil.isEmpty(supress, true)) {
4371                                    config.setSupressWSBeforeArg(Caster.toBooleanValue(supress, true));
4372                            }
4373                            else if (hasCS) {
4374                                    config.setSupressWSBeforeArg(configServer.getSupressWSBeforeArg());
4375                            }
4376                    }
4377    
4378                    // do dot notation keys upper case
4379                    if (mode == ConfigImpl.MODE_STRICT) {
4380                            config.setDotNotationUpperCase(false);
4381                    }
4382                    else {
4383                            String _case = compiler.getAttribute("dot-notation-upper-case");
4384                            if (!StringUtil.isEmpty(_case, true)) {
4385                                    config.setDotNotationUpperCase(Caster.toBooleanValue(_case, true));
4386                            }
4387                            else if (hasCS) {
4388                                    config.setDotNotationUpperCase(configServer.getDotNotationUpperCase());
4389                            }
4390                    }
4391    
4392                    // full null support
4393                    if (!hasCS) {
4394                            boolean fns = false;
4395                            if (mode == ConfigImpl.MODE_STRICT) {
4396                                    fns = true;
4397                            }
4398                            else {
4399                                    String str = compiler.getAttribute("full-null-support");
4400    
4401                                    if (!StringUtil.isEmpty(str, true)) {
4402                                            fns = Caster.toBooleanValue(str, false);
4403                                    }
4404                            }
4405                            NullSupportHelper.fullNullSupport = fns;
4406                            ((ConfigServerImpl) config).setFullNullSupport(fns);
4407                    }
4408            }
4409    
4410            /**
4411             * @param configServer
4412             * @param config
4413             * @param doc
4414             * @throws IOException
4415             * @throws PageException
4416             */
4417            private static void loadApplication(ConfigServerImpl configServer, ConfigImpl config, Document doc, int mode) throws IOException, PageException {
4418                    boolean hasCS = configServer != null;
4419                    boolean hasAccess = ConfigWebUtil.hasAccess(config, SecurityManager.TYPE_SETTING);
4420    
4421                    Element application = getChildByName(doc.getDocumentElement(), "application");
4422                    Element scope = getChildByName(doc.getDocumentElement(), "scope");
4423                    
4424                    // Scope Logger
4425                    String strLogger = scope.getAttribute("log");
4426                    if (StringUtil.isEmpty(strLogger) && hasCS)
4427                            strLogger = configServer.getScopeLogger().getSource();
4428                    if (StringUtil.isEmpty(strLogger))
4429                            strLogger = "{railo-web}/logs/scope.log";
4430                    int logLevel = LogUtil.toIntType(scope.getAttribute("log-level"), Log.LEVEL_ERROR);
4431                    config.setScopeLogger(ConfigWebUtil.getLogAndSource(configServer, config, strLogger, true, logLevel));
4432    
4433                    // Application Logger
4434                    strLogger = application.getAttribute("application-log");
4435                    if (StringUtil.isEmpty(strLogger) && hasCS)
4436                            strLogger = configServer.getApplicationLogger().getSource();
4437                    if (StringUtil.isEmpty(strLogger)) strLogger = "{railo-web}/logs/application.log";
4438                    logLevel = LogUtil.toIntType(application.getAttribute("application-log-level"), Log.LEVEL_ERROR);
4439                    config.setApplicationLogger(ConfigWebUtil.getLogAndSource(configServer, config, strLogger, true, logLevel));
4440    
4441                    // Exception Logger
4442                    strLogger = application.getAttribute("exception-log");
4443                    if (StringUtil.isEmpty(strLogger) && hasCS)
4444                            strLogger = configServer.getExceptionLogger().getSource();
4445                    if (StringUtil.isEmpty(strLogger)) strLogger = "{railo-web}/logs/exception.log";
4446                    logLevel = LogUtil.toIntType(application.getAttribute("exception-log-level"), Log.LEVEL_ERROR);
4447                    config.setExceptionLogger(ConfigWebUtil.getLogAndSource(configServer, config, strLogger, true, logLevel));
4448    
4449                    // Trace Logger
4450                    strLogger = application.getAttribute("trace-log");
4451                    if (StringUtil.isEmpty(strLogger) && hasCS)
4452                            strLogger = configServer.getTraceLogger().getSource();
4453                    if (StringUtil.isEmpty(strLogger)) strLogger = "{railo-web}/logs/trace.log";
4454                    logLevel = LogUtil.toIntType(application.getAttribute("trace-log-level"), Log.LEVEL_INFO);
4455                    config.setTraceLogger(ConfigWebUtil.getLogAndSource(configServer, config, strLogger, true, logLevel));
4456    
4457                    // Thread Logger
4458                    strLogger = hasAccess ? application.getAttribute("thread-log") : "";
4459                    if (StringUtil.isEmpty(strLogger) && hasCS)
4460                            strLogger = configServer.getThreadLogger().getSource();
4461                    if (StringUtil.isEmpty(strLogger))
4462                            strLogger = "{railo-config}/logs/thread.log";
4463    
4464                    logLevel = LogUtil.toIntType(application.getAttribute("thread-log-level"), Log.LEVEL_ERROR);
4465                    config.setThreadLogger(ConfigWebUtil.getLogAndSource(configServer, config, strLogger, true, logLevel));
4466    
4467                    // deploy Logger
4468                    strLogger = hasAccess ? application.getAttribute("deploy-log") : "";
4469                    if (StringUtil.isEmpty(strLogger) && hasCS)
4470                            strLogger = configServer.getDeployLogger().getSource();
4471                    if (StringUtil.isEmpty(strLogger))
4472                            strLogger = "{railo-config}/logs/deploy.log";
4473    
4474                    logLevel = LogUtil.toIntType(application.getAttribute("deploy-log-level"), Log.LEVEL_INFO);
4475                    config.setDeployLogger(ConfigWebUtil.getLogAndSource(configServer, config, strLogger, true, logLevel));
4476    
4477                    // Listener type
4478                    ApplicationListener listener;
4479                    if (mode == ConfigImpl.MODE_STRICT) {
4480                            listener = new ModernAppListener();
4481                    }
4482                    else {
4483    
4484                            listener = ConfigWebUtil.loadListener(application.getAttribute("listener-type"), null);
4485    
4486                            if (listener == null) {
4487                                    if (hasCS && configServer.getApplicationListener() != null)
4488                                            listener = ConfigWebUtil.loadListener(configServer.getApplicationListener().getType(), null);
4489                                    if (listener == null)
4490                                            listener = new MixedAppListener();
4491                            }
4492                    }
4493    
4494                    // Listener Mode
4495                    int listenerMode = ConfigWebUtil.toListenerMode(application.getAttribute("listener-mode"), -1);
4496                    if (listenerMode == -1) {
4497                            if (hasCS)
4498                                    listenerMode = configServer.getApplicationListener() == null ? ApplicationListener.MODE_CURRENT2ROOT : configServer.getApplicationListener().getMode();
4499                            else
4500                                    listenerMode = ApplicationListener.MODE_CURRENT2ROOT;
4501                    }
4502    
4503                    listener.setMode(listenerMode);
4504                    config.setApplicationListener(listener);
4505    
4506                    // Req Timeout URL
4507                    if (mode == ConfigImpl.MODE_STRICT) {
4508                            config.setAllowURLRequestTimeout(false);
4509                    }
4510                    else {
4511                            String allowURLReqTimeout = application.getAttribute("allow-url-requesttimeout");
4512                            if (hasAccess && !StringUtil.isEmpty(allowURLReqTimeout)) {
4513                                    config.setAllowURLRequestTimeout(Caster.toBooleanValue(allowURLReqTimeout, false));
4514                            }
4515                            else if (hasCS)
4516                                    config.setAllowURLRequestTimeout(configServer.isAllowURLRequestTimeout());
4517                    }
4518    
4519                    // Req Timeout
4520                    TimeSpan ts=null;
4521                    if(hasAccess) {
4522                            String reqTimeoutApplication = application.getAttribute("requesttimeout");
4523                            String reqTimeoutScope = scope.getAttribute("requesttimeout"); // deprecated
4524                            
4525                            if (!StringUtil.isEmpty(reqTimeoutApplication)) ts=Caster.toTimespan(reqTimeoutApplication);
4526                            if (ts==null && !StringUtil.isEmpty(reqTimeoutScope))  ts=Caster.toTimespan(reqTimeoutScope);
4527                    }
4528                    
4529                    if (ts!=null && ts.getMillis()>0) config.setRequestTimeout(ts);
4530                    else if (hasCS) config.setRequestTimeout(configServer.getRequestTimeout());
4531    
4532                    // Req Timeout Log
4533                    String strReqTimeLog = application.getAttribute("requesttimeout-log");
4534                    if (StringUtil.isEmpty(strReqTimeLog))
4535                            strReqTimeLog = scope.getAttribute("requesttimeout-log"); // deprecated
4536                    logLevel = LogUtil.toIntType(application.getAttribute("requesttimeout-log-level"), -1);
4537                    if (logLevel == -1)
4538                            logLevel = LogUtil.toIntType(scope.getAttribute("requesttimeout-log-level"), Log.LEVEL_ERROR); // deprecated
4539                    config.setRequestTimeoutLogger(ConfigWebUtil.getLogAndSource(configServer, config, strReqTimeLog, hasAccess, logLevel));
4540    
4541                    // script-protect
4542                    String strScriptProtect = application.getAttribute("script-protect");
4543    
4544                    if (hasAccess && !StringUtil.isEmpty(strScriptProtect)) {
4545                            // print.err("sp:"+strScriptProtect);
4546                            config.setScriptProtect(AppListenerUtil.translateScriptProtect(strScriptProtect));
4547                    }
4548                    else if (hasCS)
4549                            config.setScriptProtect(configServer.getScriptProtect());
4550    
4551                    // classic-date-parsing
4552                    if (config instanceof ConfigServer) {
4553                            if (mode == ConfigImpl.MODE_STRICT) {
4554                                    DateCaster.classicStyle = true;
4555                            }
4556                            else {
4557                                    String strClassicDateParsing = application.getAttribute("classic-date-parsing");
4558    
4559                                    if (!StringUtil.isEmpty(strClassicDateParsing)) {
4560                                            DateCaster.classicStyle = Caster.toBooleanValue(strClassicDateParsing, false);
4561                                    }
4562                            }
4563                    }
4564    
4565                    // Cache
4566                    Resource configDir = config.getConfigDir();
4567                    String strCacheDirectory = application.getAttribute("cache-directory");
4568                    if (hasAccess && !StringUtil.isEmpty(strCacheDirectory)) {
4569                            strCacheDirectory = ConfigWebUtil.translateOldPath(strCacheDirectory);
4570                            Resource res = ConfigWebUtil.getFile(configDir, strCacheDirectory, "cache", configDir, FileUtil.TYPE_DIR, config);
4571                            config.setCacheDir(res);
4572                    }
4573                    else {
4574                            config.setCacheDir(configDir.getRealResource("cache"));
4575                    }
4576    
4577                    String strMax = application.getAttribute("cache-directory-max-size");
4578                    if (hasAccess && !StringUtil.isEmpty(strMax)) {
4579                            config.setCacheDirSize(ByteSizeParser.parseByteSizeDefinition(strMax, config.getCacheDirSize()));
4580                    }
4581                    else if (hasCS)
4582                            config.setCacheDirSize(configServer.getCacheDirSize());
4583    
4584                    // admin sync
4585                    String strClass = application.getAttribute("admin-sync-class");
4586                    if (StringUtil.isEmpty(strClass))
4587                            strClass = scope.getAttribute("admin-sync");
4588                    if (StringUtil.isEmpty(strClass))
4589                            strClass = scope.getAttribute("admin-synchronisation-class");
4590                    if (StringUtil.isEmpty(strClass))
4591                            strClass = scope.getAttribute("admin-synchronisation");
4592    
4593                    if (hasAccess && !StringUtil.isEmpty(strClass)) {
4594                            try {
4595                                    Class clazz = ClassUtil.loadClass(config.getClassLoader(), strClass);
4596                                    if (!Reflector.isInstaneOf(clazz, AdminSync.class))
4597                                            throw new ApplicationException("class [" + clazz.getName() + "] does not implement interface [" + AdminSync.class.getName() + "]");
4598                                    config.setAdminSyncClass(clazz);
4599    
4600                            }
4601                            catch (ClassException e) {
4602                                    e.printStackTrace();
4603                            }
4604                    }
4605                    else if (hasCS)
4606                            config.setAdminSyncClass(configServer.getAdminSyncClass());
4607            }
4608    
4609            /**
4610             * cast a string value to a int
4611             * 
4612             * @param value
4613             *            String value represent a int value
4614             * @param defaultValue
4615             *            if can't cast to a int is value will be returned
4616             * @return int value
4617             */
4618            public static int toInt(String value, int defaultValue) {
4619    
4620                    if (value == null || value.trim().length() == 0)
4621                            return defaultValue;
4622                    int intValue = Caster.toIntValue(value.trim(), Integer.MIN_VALUE);
4623                    if (intValue == Integer.MIN_VALUE)
4624                            return defaultValue;
4625                    return intValue;
4626            }
4627    
4628            public static long toLong(String value, long defaultValue) {
4629    
4630                    if (value == null || value.trim().length() == 0)
4631                            return defaultValue;
4632                    long longValue = Caster.toLongValue(value.trim(), Long.MIN_VALUE);
4633                    if (longValue == Long.MIN_VALUE)
4634                            return defaultValue;
4635                    return longValue;
4636            }
4637    
4638            /**
4639             * cast a string value to a boolean
4640             * 
4641             * @param value
4642             *            String value represent a booolean ("yes", "no","true" aso.)
4643             * @param defaultValue
4644             *            if can't cast to a boolean is value will be returned
4645             * @return boolean value
4646             */
4647            private static boolean toBoolean(String value, boolean defaultValue) {
4648    
4649                    if (value == null || value.trim().length() == 0)
4650                            return defaultValue;
4651    
4652                    try {
4653                            return Caster.toBooleanValue(value.trim());
4654                    }
4655                    catch (PageException e) {
4656                            return defaultValue;
4657                    }
4658            }
4659    
4660            /* *
4661             * return first direct child Elements of a Element with given Name and
4662             * matching attribute
4663             * 
4664             * @param parent
4665             * 
4666             * @param nodeName
4667             * 
4668             * @param attributeName
4669             * 
4670             * @param attributeValue
4671             * 
4672             * @return matching children / private static Element getChildByName(Node
4673             * parent, String nodeName, String attributeName, String attributeValue) {
4674             * if(parent==null) return null; NodeList list=parent.getChildNodes(); int
4675             * len=list.getLength();
4676             * 
4677             * for(int i=0;i<len;i++) { Node node=list.item(i);
4678             * if(node.getNodeType()==Node.ELEMENT_NODE &&
4679             * node.getNodeName().equalsIgnoreCase(nodeName)) { Element el=(Element)
4680             * node; if(el.getAttribute(attributeName).equalsIgnoreCase(attributeValue))
4681             * return el; } } return null; }
4682             */
4683    
4684            /**
4685             * return first direct child Elements of a Element with given Name
4686             * 
4687             * @param parent
4688             * @param nodeName
4689             * @return matching children
4690             */
4691            public static Element getChildByName(Node parent, String nodeName) {
4692                    return getChildByName(parent, nodeName, false);
4693            }
4694    
4695            public static Element getChildByName(Node parent, String nodeName, boolean insertBefore) {
4696                    return getChildByName(parent, nodeName, insertBefore, false);
4697            }
4698    
4699            public static Element getChildByName(Node parent, String nodeName, boolean insertBefore, boolean doNotCreate) {
4700                    if (parent == null)
4701                            return null;
4702                    NodeList list = parent.getChildNodes();
4703                    int len = list.getLength();
4704    
4705                    for (int i = 0; i < len; i++) {
4706                            Node node = list.item(i);
4707    
4708                            if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equalsIgnoreCase(nodeName)) {
4709                                    return (Element) node;
4710                            }
4711                    }
4712                    if (doNotCreate)
4713                            return null;
4714    
4715                    Element newEl = parent.getOwnerDocument().createElement(nodeName);
4716                    if (insertBefore)
4717                            parent.insertBefore(newEl, parent.getFirstChild());
4718                    else
4719                            parent.appendChild(newEl);
4720    
4721                    return newEl;
4722            }
4723    
4724            /**
4725             * return all direct child Elements of a Element with given Name
4726             * 
4727             * @param parent
4728             * @param nodeName
4729             * @return matching children
4730             */
4731            public static Element[] getChildren(Node parent, String nodeName) {
4732                    if (parent == null)
4733                            return new Element[0];
4734                    NodeList list = parent.getChildNodes();
4735                    int len = list.getLength();
4736                    ArrayList rtn = new ArrayList();
4737    
4738                    for (int i = 0; i < len; i++) {
4739                            Node node = list.item(i);
4740                            if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equalsIgnoreCase(nodeName)) {
4741                                    rtn.add(node);
4742                            }
4743                    }
4744                    return (Element[]) rtn.toArray(new Element[rtn.size()]);
4745            }
4746    
4747            public static class MonitorTemp {
4748    
4749                    public final Object obj;
4750                    public final String name;
4751                    public final boolean log;
4752    
4753                    public MonitorTemp(Object obj, String name, boolean log) {
4754                            this.obj = obj;
4755                            this.name = name;
4756                            this.log = log;
4757                    }
4758    
4759            }
4760    }