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