001    package railo.runtime.config;
002    
003    import java.io.ByteArrayInputStream;
004    import java.io.File;
005    import java.io.IOException;
006    import java.io.InputStream;
007    import java.net.MalformedURLException;
008    import java.net.URL;
009    import java.util.ArrayList;
010    import java.util.Iterator;
011    import java.util.List;
012    import java.util.Map;
013    import java.util.Map.Entry;
014    import java.util.Set;
015    import java.util.zip.ZipInputStream;
016    
017    import javax.servlet.ServletException;
018    
019    import org.apache.xerces.parsers.DOMParser;
020    import org.w3c.dom.DOMException;
021    import org.w3c.dom.Document;
022    import org.w3c.dom.Element;
023    import org.xml.sax.InputSource;
024    import org.xml.sax.SAXException;
025    
026    import railo.print;
027    import railo.commons.digest.MD5;
028    import railo.commons.io.FileUtil;
029    import railo.commons.io.IOUtil;
030    import railo.commons.io.SystemUtil;
031    import railo.commons.io.cache.Cache;
032    import railo.commons.io.log.LogUtil;
033    import railo.commons.io.res.Resource;
034    import railo.commons.io.res.ResourceProvider;
035    import railo.commons.io.res.filter.ResourceFilter;
036    import railo.commons.io.res.filter.ResourceNameFilter;
037    import railo.commons.io.res.type.s3.S3ResourceProvider;
038    import railo.commons.io.res.util.ResourceUtil;
039    import railo.commons.lang.ClassException;
040    import railo.commons.lang.ClassUtil;
041    import railo.commons.lang.StringUtil;
042    import railo.commons.lang.SystemOut;
043    import railo.commons.net.HTTPUtil;
044    import railo.commons.net.IPRange;
045    import railo.commons.net.URLEncoder;
046    import railo.commons.net.http.HTTPEngine;
047    import railo.commons.net.http.HTTPResponse;
048    import railo.loader.TP;
049    import railo.loader.engine.CFMLEngineFactory;
050    import railo.loader.util.ExtensionFilter;
051    import railo.runtime.Info;
052    import railo.runtime.cache.CacheConnection;
053    import railo.runtime.cfx.CFXTagException;
054    import railo.runtime.cfx.CFXTagPool;
055    import railo.runtime.converter.ConverterException;
056    import railo.runtime.converter.WDDXConverter;
057    import railo.runtime.crypt.BlowfishEasy;
058    import railo.runtime.db.DataSource;
059    import railo.runtime.exp.ApplicationException;
060    import railo.runtime.exp.ExpressionException;
061    import railo.runtime.exp.HTTPException;
062    import railo.runtime.exp.PageException;
063    import railo.runtime.exp.SecurityException;
064    import railo.runtime.extension.Extension;
065    import railo.runtime.extension.RHExtension;
066    import railo.runtime.functions.cache.Util;
067    import railo.runtime.functions.other.CreateObject;
068    import railo.runtime.functions.other.URLEncodedFormat;
069    import railo.runtime.functions.string.Hash;
070    import railo.runtime.gateway.GatewayEntry;
071    import railo.runtime.gateway.GatewayEntryImpl;
072    import railo.runtime.listener.AppListenerUtil;
073    import railo.runtime.net.ntp.NtpClient;
074    import railo.runtime.op.Caster;
075    import railo.runtime.op.Decision;
076    import railo.runtime.orm.ORMConfiguration;
077    import railo.runtime.orm.ORMConfigurationImpl;
078    import railo.runtime.reflection.Reflector;
079    import railo.runtime.security.SecurityManager;
080    import railo.runtime.security.SecurityManagerImpl;
081    import railo.runtime.security.SerialNumber;
082    import railo.runtime.text.xml.XMLCaster;
083    import railo.runtime.text.xml.XMLUtil;
084    import railo.runtime.type.Array;
085    import railo.runtime.type.ArrayImpl;
086    import railo.runtime.type.Collection.Key;
087    import railo.runtime.type.KeyImpl;
088    import railo.runtime.type.Query;
089    import railo.runtime.type.QueryImpl;
090    import railo.runtime.type.Struct;
091    import railo.runtime.type.dt.TimeSpan;
092    import railo.runtime.type.scope.Cluster;
093    import railo.runtime.type.scope.ClusterNotSupported;
094    import railo.runtime.type.scope.ClusterRemote;
095    import railo.runtime.type.scope.ScopeContext;
096    import railo.runtime.type.util.ArrayUtil;
097    import railo.runtime.type.util.ComponentUtil;
098    import railo.runtime.type.util.ListUtil;
099    import railo.runtime.video.VideoExecuter;
100    import railo.runtime.video.VideoExecuterNotSupported;
101    import railo.transformer.library.function.FunctionLibException;
102    import railo.transformer.library.tag.TagLibException;
103    
104    import com.allaire.cfx.CustomTag;
105    
106    /**
107     * 
108     */
109    public final class ConfigWebAdmin {
110        
111        //private static final Object NULL = new Object();
112            private ConfigImpl config;
113        private Document doc;
114            private String password;
115        //private SecurityManager accessorx;
116    
117    
118        /**
119         * 
120         * @param config
121         * @param password
122         * @return returns a new instance of the class
123         * @throws SAXException
124         * @throws IOException
125         */
126        public static ConfigWebAdmin newInstance(ConfigImpl config, String password) throws SAXException, IOException {
127            return new ConfigWebAdmin(config, password);
128        }
129        
130    
131        private void checkWriteAccess() throws SecurityException {
132            ConfigWebUtil.checkGeneralWriteAccess(config,password);
133            }
134        private void checkReadAccess() throws SecurityException {
135            ConfigWebUtil.checkGeneralReadAccess(config,password);
136            }
137        
138        /**
139         * @param password
140         * @throws ExpressionException 
141         */
142        public void setPassword(String password) throws SecurityException {
143            checkWriteAccess();
144            Element root=doc.getDocumentElement();
145            if(password==null || password.length()==0) {
146                if(root.getAttribute("password")!=null)
147                    root.removeAttribute("password");
148            }
149            else {
150                root.setAttribute("password",new BlowfishEasy("tpwisgh").encryptString(password));
151            }
152        }
153    
154        public void setVersion(double version) {
155            
156            Element root=doc.getDocumentElement();
157            String str = Caster.toString(version);
158            if(str.length()>3)str=str.substring(0,3);
159            root.setAttribute("version",str); 
160            
161        }
162        /*public void setId(String id) {
163            
164            Element root=doc.getDocumentElement();
165            if(!StringUtil.isEmpty(root.getAttribute("id"))) return;
166            root.setAttribute("id",id); 
167            try {
168                            store(config);
169                    } 
170            catch (Exception e) {}
171        }*/
172        
173        /**
174         * @param contextPath
175         * @param password
176         * @throws FunctionLibException
177         * @throws TagLibException
178         * @throws IOException
179         * @throws ClassNotFoundException
180         * @throws SAXException
181         * @throws PageException
182         */
183        public void setPassword(String contextPath,String password) throws PageException, SAXException, ClassException, IOException, TagLibException, FunctionLibException {
184            checkWriteAccess();
185            if(contextPath==null || contextPath.length()==0 || !(config instanceof ConfigServerImpl)) {
186                setPassword(password);
187            }
188            else { 
189                ConfigServerImpl cs=(ConfigServerImpl)config;
190                ConfigWebImpl cw=cs.getConfigWebImpl(contextPath);
191                if(cw!=null)cw.setPassword(false,cw.getPassword(),password);
192            }
193        }
194        
195        private ConfigWebAdmin(ConfigImpl config, String password) throws SAXException, IOException {
196            this.config=config;
197            this.password=password;
198            doc=loadDocument(config.getConfigFile());
199            if(config.getVersion()<2.0D){
200                    try {
201                            updateTo2(config);
202                    } catch (Exception e) {
203                            e.printStackTrace();
204                    }
205            }
206            //setId(config.getId());
207        }    
208        // FUTURE resources for old version of railo remove in newer
209        private void updateTo2(ConfigImpl config) throws PageException, ClassException, SAXException, IOException, TagLibException, FunctionLibException {
210    //       Server
211            if(config instanceof ConfigServer) {
212                    addResourceProvider(
213                                    "ftp",
214                                    "railo.commons.io.res.type.ftp.FTPResourceProvider",
215                                    "lock-timeout:20000;socket-timeout:-1;client-timeout:60000");
216                    // zip
217                    addResourceProvider(
218                                    "zip",
219                                    "railo.commons.io.res.type.zip.ZipResourceProvider",
220                                    "lock-timeout:1000;case-sensitive:true;");
221                    // tar
222                    addResourceProvider(
223                                    "tar",
224                                    "railo.commons.io.res.type.tar.TarResourceProvider",
225                                    "lock-timeout:1000;case-sensitive:true;");
226                    // tgz
227                    addResourceProvider(
228                                    "tgz",
229                                    "railo.commons.io.res.type.tgz.TGZResourceProvider",
230                                    "lock-timeout:1000;case-sensitive:true;");
231                    
232                    
233                    
234            }
235            else {
236                    // ram
237                    addResourceProvider(
238                                    "ram",
239                                    "railo.commons.io.res.type.ram.RamResourceProvider",
240                                    "case-sensitive:true;lock-timeout:1000;");
241                    
242            }
243            setVersion(Caster.toDoubleValue(Info.getVersionAsString().substring(0,3),1.0D));
244            _store(config);
245        }
246        
247        public static void checkForChangesInConfigFile(Config config) {
248            ConfigImpl ci=(ConfigImpl) config;
249                    if(!ci.checkForChangesInConfigFile()) return;
250                    
251                    Resource file = config.getConfigFile();
252                    long diff=file.lastModified()-ci.lastModified();
253                    if(diff<10 && diff>-10) return; 
254                    // reload
255                    try {
256                            ConfigWebAdmin admin = ConfigWebAdmin.newInstance(ci, null);
257                            admin.reload(ci, false);
258                            SystemOut.printDate(ci.getOutWriter(), "reloaded the configuration ["+file+"] automaticly");
259                    } 
260                    catch (Throwable t) {
261                            t.printStackTrace();
262                    }
263            }
264        
265        
266    
267        private void addResourceProvider(String scheme,String clazz,String arguments) throws SecurityException {
268            checkWriteAccess();
269            
270            Element resources=_getRootElement("resources");
271            Element[] rpElements = ConfigWebFactory.getChildren(resources,"resource-provider");
272            String s;
273            // update
274            if(rpElements!=null) {
275                    for(int i=0;i<rpElements.length;i++) {
276                            s=rpElements[i].getAttribute("scheme");
277                            if(!StringUtil.isEmpty(s) && s.equalsIgnoreCase(scheme))        {
278                                    rpElements[i].setAttribute("class", clazz);
279                                    rpElements[i].setAttribute("scheme", scheme);
280                                    rpElements[i].setAttribute("arguments", arguments);
281                                    return;
282                            }
283                    }
284            }
285            // Insert
286            Element el=doc.createElement("resource-provider");
287            resources.appendChild(XMLCaster.toRawNode(el));
288            el.setAttribute("class", clazz);
289            el.setAttribute("scheme", scheme);
290            el.setAttribute("arguments", arguments);
291            }
292    
293    
294            /**
295         * load XML Document from XML File
296         * @param config
297         * @param xmlFile XML File to read
298         * @return returns the Document
299         * @throws SAXException
300         * @throws IOException
301         */
302        private static Document loadDocument(Resource xmlFile) throws SAXException, IOException {
303            DOMParser parser = new DOMParser();
304            InputStream is=null;
305            try {
306                    is = IOUtil.toBufferedInputStream(xmlFile.getInputStream());
307                InputSource source = new InputSource(is);
308                parser.parse(source);
309            }
310            finally {
311                    IOUtil.closeEL(is);
312            }
313                return parser.getDocument();
314        }
315        
316        private static synchronized void _store(ConfigImpl config) throws PageException, SAXException, ClassException, IOException, TagLibException, FunctionLibException  {
317            ConfigWebAdmin admin = new ConfigWebAdmin(config, null);
318            admin._reload(config, true);
319        }
320    
321        private synchronized void _store() throws PageException, SAXException, ClassException, IOException, TagLibException, FunctionLibException  {
322            _reload(config, true);
323        }
324        
325        public synchronized void store() throws PageException, SAXException, ClassException, IOException, TagLibException, FunctionLibException  {
326            reload(config, true);
327        }
328        
329        private synchronized void reload(ConfigImpl config, boolean storeInMemoryData) throws PageException, SAXException, ClassException, IOException, TagLibException, FunctionLibException  {
330            if(storeInMemoryData)checkWriteAccess();
331            _reload(config, storeInMemoryData);
332        }
333    
334        private synchronized void _reload(ConfigImpl config, boolean storeInMemoryData) throws PageException, SAXException, ClassException, IOException, TagLibException, FunctionLibException  {
335            renameOldstyleCFX();
336            
337            createAbort();
338            if(config instanceof ConfigServerImpl) {
339                    if(storeInMemoryData)XMLCaster.writeTo(doc,config.getConfigFile());
340                
341                ConfigServerImpl cs=(ConfigServerImpl) config;
342                ConfigServerFactory.reloadInstance(cs);
343                ConfigWeb[] webs=cs.getConfigWebs();
344                for(int i=0;i<webs.length;i++) {
345                    ConfigWebFactory.reloadInstance((ConfigServerImpl) config,(ConfigWebImpl)webs[i],true);
346                }
347            }
348            else {
349                    if(storeInMemoryData)XMLCaster.writeTo(doc,config.getConfigFile());
350                //SystemUtil.sleep(10);
351                ConfigServerImpl cs=((ConfigWebImpl)config).getConfigServerImpl();
352                
353                ConfigWebFactory.reloadInstance(cs,(ConfigWebImpl)config,false);
354            }
355        }
356        
357        
358        
359    
360        private void createAbort() {
361            try {
362                    ConfigWebFactory.getChildByName(doc.getDocumentElement(),"cfabort",true);
363            }
364            catch(Throwable t) {}
365        }
366    
367            /**
368         * sets Mail Logger to Config
369         * @param logFile
370         * @param level 
371         * @throws PageException 
372         */
373        public void setMailLog(String logFile, String level) throws PageException {
374            checkWriteAccess();
375            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_MAIL);
376            
377            if(!hasAccess)
378                throw new SecurityException("no access to update mail server settings");
379            ConfigWebUtil.getFile(config,config.getRootDirectory(),logFile,FileUtil.TYPE_FILE);
380            
381            Element mail=_getRootElement("mail");
382            mail.setAttribute("log",logFile);
383            mail.setAttribute("log-level",level);
384            //config.setMailLogger(logFile.getCanonicalPath());
385        }
386    
387        /**
388         * sets if spool is enable or not
389         * @param spoolEnable
390         * @throws SecurityException
391         */
392        public void setMailSpoolEnable(Boolean spoolEnable) throws SecurityException {
393            checkWriteAccess();
394            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_MAIL);
395            
396            if(!hasAccess)
397                throw new SecurityException("no access to update mail server settings");
398            Element mail=_getRootElement("mail");
399            mail.setAttribute("spool-enable",Caster.toString(spoolEnable,""));
400            //config.setMailSpoolEnable(spoolEnable);
401        }
402    
403        /**
404         * sets if er interval is enable or not
405         * @param interval
406         * @throws SecurityException
407         */
408        public void setMailSpoolInterval(Integer interval) throws SecurityException {
409            checkWriteAccess();
410            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_MAIL);
411            if(!hasAccess)
412                throw new SecurityException("no access to update mail server settings");
413            Element mail=_getRootElement("mail");
414            mail.setAttribute("spool-interval",Caster.toString(interval,""));
415            //config.setMailSpoolInterval(interval);
416        }
417    
418        /**
419         * sets the timeout for the spooler for one job
420         * @param timeout
421         * @throws SecurityException
422         */
423        public void setMailTimeout(Integer timeout) throws SecurityException {
424            checkWriteAccess();
425            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_MAIL);
426            if(!hasAccess)
427                throw new SecurityException("no access to update mail server settings");
428            Element mail=_getRootElement("mail");
429            mail.setAttribute("timeout",Caster.toString(timeout,""));
430            //config.setMailTimeout(timeout);
431        }
432        
433        /**
434         * sets the charset for the mail
435         * @param timeout
436         * @throws SecurityException
437         */
438        public void setMailDefaultCharset(String charset) throws PageException {
439            checkWriteAccess();
440            boolean hasAccess = ConfigWebUtil.hasAccess(config, SecurityManager.TYPE_MAIL);
441            if(!hasAccess) throw new SecurityException("no access to update mail server settings");
442            
443            if(!StringUtil.isEmpty(charset)){
444                            try {
445                                    IOUtil.checkEncoding(charset);
446                            } catch (IOException e) {
447                                    throw Caster.toPageException(e);
448                            }
449            }
450            
451                    Element mail=_getRootElement("mail");
452            mail.setAttribute("default-encoding",charset);
453            //config.setMailDefaultEncoding(charset);               
454            }
455    
456            /**
457         * insert or update a mailserver on system
458         * @param hostName
459         * @param username
460         * @param password
461         * @param port
462             * @param ssl 
463             * @param tls 
464         * @throws PageException 
465         */
466        public void updateMailServer(String hostName,String username,String password, int port, boolean tls, boolean ssl) throws PageException {
467            checkWriteAccess();
468            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_MAIL);
469            if(!hasAccess)
470                throw new SecurityException("no access to update mail server settings");
471            
472            /*try {
473                SMTPVerifier.verify(hostName,username,password,port);
474            } catch (SMTPException e) {
475                throw Caster.toPageException(e);
476            }*/
477            
478            Element mail=_getRootElement("mail");
479            if(port<1) port=21;
480    
481            if(hostName==null || hostName.trim().length()==0)
482                throw new ExpressionException("Host (SMTP) can be a empty value");
483            hostName=hostName.trim();
484            
485            
486            Element[] children = ConfigWebFactory.getChildren(mail,"server");
487            
488            // Update
489            for(int i=0;i<children.length;i++) {
490                Element el=children[i];
491                String smtp=el.getAttribute("smtp");
492                            if(smtp!=null && smtp.equalsIgnoreCase(hostName)) {
493                            el.setAttribute("username",username);
494                            el.setAttribute("password",ConfigWebFactory.encrypt(password));
495                            el.setAttribute("port",Caster.toString(port));
496                            el.setAttribute("tls",Caster.toString(tls));
497                            el.setAttribute("ssl",Caster.toString(ssl));
498                            return ;
499                            }
500            }
501            
502            // Insert
503            Element server = doc.createElement("server");
504            server.setAttribute("smtp",hostName);
505            server.setAttribute("username",username);
506            server.setAttribute("password",ConfigWebFactory.encrypt(password));
507            server.setAttribute("port",Caster.toString(port));
508            server.setAttribute("tls",Caster.toString(tls));
509            server.setAttribute("ssl",Caster.toString(ssl));
510            mail.appendChild(XMLCaster.toRawNode(server));
511            
512        }
513    
514        /**
515         *removes a mailserver from system
516         * @param hostName
517         * @throws SecurityException 
518         */
519        public void removeMailServer(String hostName) throws SecurityException {
520            checkWriteAccess();
521            
522            Element mail=_getRootElement("mail");
523            Element[] children = ConfigWebFactory.getChildren(mail,"server");
524            if(children.length>0) {
525                    for(int i=0;i<children.length;i++) {
526                        Element el=children[i];
527                        String smtp=el.getAttribute("smtp");
528                                    if(smtp!=null && smtp.equalsIgnoreCase(hostName)) {
529                                    mail.removeChild(children[i]);
530                                    }
531                    }
532            }
533        }
534        
535        static void updateMapping(ConfigImpl config, String virtual, String physical,String archive,String primary, short inspect, boolean toplevel) throws SAXException, IOException, PageException {
536            ConfigWebAdmin admin = new ConfigWebAdmin(config, null);
537            admin._updateMapping(virtual, physical, archive, primary, inspect, toplevel);
538            admin._store();
539        }
540        
541    
542        static void updateComponentMapping(ConfigImpl config, String virtual, String physical,String archive,String primary, short inspect) throws SAXException, IOException, PageException {
543            ConfigWebAdmin admin = new ConfigWebAdmin(config, null);
544            admin._updateComponentMapping(virtual, physical, archive, primary, inspect);
545            admin._store();
546        }
547        
548    
549        static void updateCustomTagMapping(ConfigImpl config, String virtual, String physical,String archive,String primary, short inspect) throws SAXException, IOException, PageException {
550            ConfigWebAdmin admin = new ConfigWebAdmin(config, null);
551            admin._updateCustomTag(virtual, physical, archive, primary, inspect);
552            admin._store();
553        }
554    
555        /**
556         * insert or update a mapping on system
557         * @param virtual
558         * @param physical
559         * @param archive
560         * @param primary
561         * @param trusted
562         * @param toplevel 
563         * @throws ExpressionException
564         * @throws SecurityException
565         */
566        public void updateMapping(String virtual, String physical,String archive,String primary, short inspect, boolean toplevel) throws ExpressionException, SecurityException {
567            checkWriteAccess();
568            _updateMapping(virtual, physical, archive, primary, inspect, toplevel);
569        }
570        private void _updateMapping(String virtual, String physical,String archive,String primary, short inspect, boolean toplevel) throws ExpressionException, SecurityException {
571            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_MAPPING);
572            
573            virtual=virtual.trim(); 
574            if(physical==null) physical="";
575            else physical=physical.trim();
576            if(archive==null) archive="";
577            else archive=archive.trim();
578            primary=primary.trim();
579            if(!hasAccess)
580                throw new SecurityException("no access to update mappings");
581            
582            // check virtual
583                if(virtual==null || virtual.length()==0)
584                    throw new ExpressionException("virtual path cannot be a empty value");
585                virtual=virtual.replace('\\','/');
586                
587                if(!virtual.equals("/") && virtual.endsWith("/"))
588                        virtual=virtual.substring(0,virtual.length()-1);
589                
590                if(virtual.charAt(0)!='/')
591                    throw new ExpressionException("virtual path must start with [/]");
592            boolean isArchive=primary.equalsIgnoreCase("archive");
593            
594            if((physical.length()+archive.length())==0)
595                throw new ExpressionException("physical or archive must have a value");
596            
597            if(isArchive && archive.length()==0 ) isArchive=false;
598            //print.ln("isArchive:"+isArchive);
599            
600            if(!isArchive && archive.length()>0 && physical.length()==0 ) isArchive=true;
601            //print.ln("isArchive:"+isArchive);
602            
603            
604            
605            Element mappings=_getRootElement("mappings");
606            // Update
607            Element[] children = ConfigWebFactory.getChildren(mappings,"mapping");
608            for(int i=0;i<children.length;i++) {
609                String v=children[i].getAttribute("virtual");
610                if(v!=null) {
611                    if(!v.equals("/") && v.endsWith("/"))
612                        v=v.substring(0,v.length()-1);
613                  
614                        if(v.equals(virtual)) {
615                                    Element el=children[i];
616                                    if(physical.length()>0) {
617                            el.setAttribute("physical",physical);
618                        }
619                        else if(el.hasAttribute("physical")) {
620                            el.removeAttribute("physical");
621                        }
622                                    if(archive.length()>0) {
623                            el.setAttribute("archive",archive);
624                        }
625                        else if(el.hasAttribute("archive")) {
626                            el.removeAttribute("archive");
627                        }
628                                    el.setAttribute("primary",isArchive?"archive":"physical");
629                                    el.setAttribute("inspect-template",ConfigWebUtil.inspectTemplate(inspect, ""));
630                                    el.removeAttribute("trusted");
631                                    el.setAttribute("toplevel",Caster.toString(toplevel));
632                                    return ;
633                                    }
634                }
635            }
636            
637            // Insert
638            Element el=doc.createElement("mapping");
639            mappings.appendChild(el);
640            el.setAttribute("virtual",virtual);
641            if(physical.length()>0)el.setAttribute("physical",physical);
642                    if(archive.length()>0)el.setAttribute("archive",archive);
643                    el.setAttribute("primary",isArchive?"archive":"physical");
644                    el.setAttribute("inspect-template",ConfigWebUtil.inspectTemplate(inspect, ""));
645                    el.setAttribute("toplevel",Caster.toString(toplevel));
646                    
647                    // set / to the end
648                    children = ConfigWebFactory.getChildren(mappings,"mapping");
649            for(int i=0;i<children.length;i++) {
650                String v=children[i].getAttribute("virtual");
651                
652                    if(v!=null && v.equals("/")) {
653                            el=children[i];
654                            mappings.removeChild(el);
655                            mappings.appendChild(el);
656                            return ;
657                            }
658    
659            }
660                    
661        }
662        
663        public void updateRestMapping(String virtual, String physical,boolean _default) throws ExpressionException, SecurityException {
664            checkWriteAccess();
665            boolean hasAccess=true;// TODO ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_REST);
666            virtual=virtual.trim(); 
667            physical=physical.trim();
668            if(!hasAccess)
669                throw new SecurityException("no access to update REST mapping");
670            
671            // check virtual
672                if(virtual==null || virtual.length()==0)
673                    throw new ExpressionException("virtual path cannot be a empty value");
674                virtual=virtual.replace('\\','/');
675                if(virtual.equals("/"))
676                    throw new ExpressionException("virtual path cannot be /");
677            
678                
679                if(virtual.endsWith("/"))
680                        virtual=virtual.substring(0,virtual.length()-1);
681                
682                if(virtual.charAt(0)!='/') virtual="/"+virtual;
683            
684            if((physical.length())==0)
685                    throw new ExpressionException("physical path cannot be a empty value");
686            
687            Element rest=_getRootElement("rest");
688            Element[] children = ConfigWebFactory.getChildren(rest,"mapping");
689            
690            // remove existing default
691            if(_default) {
692                    for(int i=0;i<children.length;i++) {
693                        if(Caster.toBooleanValue(children[i].getAttribute("default"),false))
694                            children[i].setAttribute("default", "false");
695                    }
696            }
697            
698            // Update
699            String v;
700            Element el=null;
701            for(int i=0;i<children.length;i++) {
702                v=children[i].getAttribute("virtual");
703                if(v!=null && v.equals(virtual)) {
704                    el=children[i];
705                }
706            }
707            
708            
709            // Insert
710            if(el==null) {
711                    el=doc.createElement("mapping");
712                    rest.appendChild(el);
713            }
714            
715            el.setAttribute("virtual",virtual);
716            el.setAttribute("physical",physical);
717                    el.setAttribute("default",Caster.toString(_default));
718                                    
719        }
720    
721    
722        /**
723         * delete a mapping on system
724         * @param virtual
725         * @throws ExpressionException
726         * @throws SecurityException 
727         */
728        public void removeMapping(String virtual) throws ExpressionException, SecurityException {
729            checkWriteAccess();
730            // check parameters
731            if(virtual==null || virtual.length()==0)
732                throw new ExpressionException("virtual path cannot be a empty value");
733            virtual=virtual.replace('\\','/');
734            
735            if(!virtual.equals("/") && virtual.endsWith("/"))
736                        virtual=virtual.substring(0,virtual.length()-1);
737            if(virtual.charAt(0)!='/')
738                throw new ExpressionException("virtual path must start with [/]");
739            
740            
741            Element mappings=_getRootElement("mappings");
742    
743            Element[] children = ConfigWebFactory.getChildren(mappings,"mapping");
744            for(int i=0;i<children.length;i++) {
745                String v=children[i].getAttribute("virtual");
746                if(v!=null) {
747                    if(!v.equals("/") && v.endsWith("/"))
748                        v=v.substring(0,v.length()-1);
749                            if(v!=null && v.equals(virtual)) {
750                                    Element el=children[i];
751                                    mappings.removeChild(el);
752                                    }
753                }
754            }
755        }
756        
757    
758        public void removeRestMapping(String virtual) throws ExpressionException, SecurityException {
759            checkWriteAccess();
760            // check parameters
761            if(virtual==null || virtual.length()==0)
762                throw new ExpressionException("virtual path cannot be a empty value");
763            virtual=virtual.replace('\\','/');
764            if(virtual.equals("/"))
765                throw new ExpressionException("virtual path cannot be /");
766            
767            if(virtual.endsWith("/")) virtual=virtual.substring(0,virtual.length()-1);
768            if(virtual.charAt(0)!='/') virtual="/"+virtual;
769            
770            
771            
772            Element mappings=_getRootElement("rest");
773    
774            Element[] children = ConfigWebFactory.getChildren(mappings,"mapping");
775            for(int i=0;i<children.length;i++) {
776                String v=children[i].getAttribute("virtual");
777                if(v!=null) {
778                    if(!v.equals("/") && v.endsWith("/"))
779                        v=v.substring(0,v.length()-1);
780                            if(v!=null && v.equals(virtual)) {
781                                    Element el=children[i];
782                                    mappings.removeChild(el);
783                                    }
784                }
785            }
786        }
787    
788        /**
789         * delete a customtagmapping on system
790         * @param virtual
791         * @throws SecurityException 
792         */
793        public void removeCustomTag(String virtual) throws SecurityException {
794            checkWriteAccess();
795            
796            Element mappings=_getRootElement("custom-tag");
797            Element[] children = ConfigWebFactory.getChildren(mappings,"mapping");
798            for(int i=0;i<children.length;i++) {
799                if(virtual.equals(createVirtual(children[i])))mappings.removeChild(children[i]);
800            }
801        }
802        
803        public void removeComponentMapping(String virtual) throws SecurityException {
804            checkWriteAccess();
805            
806            Element mappings=_getRootElement("component");
807            Element[] children = ConfigWebFactory.getChildren(mappings,"mapping");
808            String v;
809            for(int i=0;i<children.length;i++) {
810                    v=createVirtual(children[i]);
811                    if(virtual.equals(v))mappings.removeChild(children[i]);
812            }
813        }
814        
815        
816    
817    
818        /**
819         * insert or update a mapping for Custom Tag
820         * @param virtual
821         * @param physical
822         * @param archive
823         * @param primary
824         * @param trusted
825         * @throws ExpressionException
826         * @throws SecurityException
827         */
828        public void updateCustomTag(String virtual,String physical,String archive,String primary, short inspect) throws ExpressionException, SecurityException {
829            checkWriteAccess();
830            _updateCustomTag(virtual, physical, archive, primary, inspect);
831        }
832        private void _updateCustomTag(String virtual,String physical,String archive,String primary, short inspect) throws ExpressionException, SecurityException {
833            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_CUSTOM_TAG);
834            if(!hasAccess)
835                throw new SecurityException("no access to change custom tag settings");
836            if(physical==null)physical="";
837            if(archive==null)archive="";
838            
839            //virtual="/custom-tag";
840            if(StringUtil.isEmpty(virtual))virtual=createVirtual(physical,archive);
841            
842            boolean isArchive=primary.equalsIgnoreCase("archive");
843            if(isArchive && archive.length()==0 ) {
844                throw new ExpressionException("archive must have a value when primary has value archive");
845            }
846            if(!isArchive && physical.length()==0 ) {
847                throw new ExpressionException("physical must have a value when primary has value physical");
848            }
849            
850            Element mappings=_getRootElement("custom-tag");
851            
852            // Update
853            String v;
854            Element[] children = ConfigWebFactory.getChildren(mappings,"mapping");
855            for(int i=0;i<children.length;i++) {
856                    Element el=children[i];
857                    v=createVirtual(el);
858                    if(v.equals(virtual)) {
859                            el.setAttribute("virtual",v);
860                            el.setAttribute("physical",physical);
861                            el.setAttribute("archive",archive);
862                            el.setAttribute("primary",primary.equalsIgnoreCase("archive")?"archive":"physical");
863                            el.setAttribute("inspect-template",ConfigWebUtil.inspectTemplate(inspect, ""));
864                            el.removeAttribute("trusted");
865                            return ;
866                            }
867            }
868            
869            // Insert
870            Element el=doc.createElement("mapping");
871            mappings.appendChild(el);
872            if(physical.length()>0)el.setAttribute("physical",physical);
873                    if(archive.length()>0)el.setAttribute("archive",archive);
874                    el.setAttribute("primary",primary.equalsIgnoreCase("archive")?"archive":"physical");
875                    el.setAttribute("inspect-template",ConfigWebUtil.inspectTemplate(inspect, ""));
876                    el.setAttribute("virtual",virtual);
877        }
878        
879        public void updateComponentMapping(String virtual,String physical,String archive,String primary, short inspect) throws ExpressionException, SecurityException {
880            checkWriteAccess();
881            _updateComponentMapping(virtual, physical, archive, primary, inspect);
882        }   
883        private void _updateComponentMapping(String virtual,String physical,String archive,String primary, short inspect) throws ExpressionException {
884            primary=primary.equalsIgnoreCase("archive")?"archive":"physical";
885            if(physical==null)physical="";
886            else physical=physical.trim();
887            
888            if(archive==null)archive="";
889            else archive=archive.trim();
890            
891            boolean isArchive=primary.equalsIgnoreCase("archive");
892            if(isArchive && archive.length()==0 ) {
893                throw new ExpressionException("archive must have a value when primary has value archive");
894            }
895            if(!isArchive && physical.length()==0 ) {
896                throw new ExpressionException("physical must have a value when primary has value physical");
897            }
898            
899            Element mappings=_getRootElement("component");
900            Element[] children = ConfigWebFactory.getChildren(mappings,"mapping");
901            Element el;
902            
903            /* ignore when exists
904            for(int i=0;i<children.length;i++) {
905                    el=children[i];
906                if(el.getAttribute("physical").equals(physical) &&
907                            el.getAttribute("archive").equals(archive) &&
908                            el.getAttribute("primary").equals(primary) &&
909                            el.getAttribute("trusted").equals(Caster.toString(trusted))){
910                    return;
911                            }
912            }*/
913            
914            
915            // Update
916            String v;
917            for(int i=0;i<children.length;i++) {
918                    el=children[i];
919                    v=createVirtual(el); // if there is no virtual defintion (old records), we use the position
920                    if(v.equals(virtual)) {
921                            el.setAttribute("virtual",v); // set to make sure it exists for the future
922                            el.setAttribute("physical",physical);
923                            el.setAttribute("archive",archive);
924                            el.setAttribute("primary",primary.equalsIgnoreCase("archive")?"archive":"physical");
925                            el.setAttribute("inspect-template",ConfigWebUtil.inspectTemplate(inspect, ""));
926                            el.removeAttribute("trusted");
927                            return ;
928                            }
929            }
930            
931            // Insert
932            el=doc.createElement("mapping");
933            mappings.appendChild(el);
934            if(physical.length()>0)el.setAttribute("physical",physical);
935                    if(archive.length()>0)el.setAttribute("archive",archive);
936                    el.setAttribute("primary",primary.equalsIgnoreCase("archive")?"archive":"physical");
937                    el.setAttribute("inspect-template",ConfigWebUtil.inspectTemplate(inspect, ""));
938                    el.setAttribute("virtual",virtual);
939        }
940    
941        
942    
943    
944        public static String createVirtual(Element el) {
945            String str = el.getAttribute("virtual");
946            if(!StringUtil.isEmpty(str)) return str;
947            
948            return  createVirtual(el.getAttribute("physical"),el.getAttribute("archive"));
949            }
950        public static String createVirtual(String physical,String archive) {
951            return  "/"+MD5.getDigestAsString(physical+":"+archive,"");
952            }
953    
954    
955            /**
956         * insert or update a Java CFX Tag
957         * @param name
958         * @param strClass
959         * @throws PageException 
960         */
961        public void updateJavaCFX(String name,String strClass) throws PageException {
962            checkWriteAccess();
963            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_CFX_SETTING);
964            
965            if(!hasAccess) throw new SecurityException("no access to change cfx settings");
966            
967            
968            try {
969                    Class clazz = ClassUtil.loadClass(config.getClassLoader(),strClass);
970                            if(!Reflector.isInstaneOf(clazz, CustomTag.class))
971                                    throw new ExpressionException("class ["+strClass+"] must implement interface ["+CustomTag.class.getName()+"]");
972               
973            } 
974            catch (ClassException e) {
975                    
976                    throw Caster.toPageException(e);
977                    }
978            
979            
980            
981            
982            if(name==null || name.length()==0)
983                throw new ExpressionException("class name can't be a empty value");
984            
985            renameOldstyleCFX();
986            
987            
988            Element tags=_getRootElement("ext-tags");
989            
990            // Update
991            Element[] children = ConfigWebFactory.getChildren(tags,"ext-tag");
992            for(int i=0;i<children.length;i++) {
993                String n=children[i].getAttribute("name");
994                
995                if(n!=null && n.equalsIgnoreCase(name)) {
996                            Element el=children[i];
997                            if(!"java".equalsIgnoreCase(el.getAttribute("type"))) throw new ExpressionException("there is already a c++ cfx tag with this name");
998                    el.setAttribute("class",strClass);
999                            el.setAttribute("type","java");
1000                            return ;
1001                            }
1002                
1003            }
1004            
1005            // Insert
1006            Element el=doc.createElement("ext-tag");
1007            tags.appendChild(el);
1008            el.setAttribute("class",strClass);
1009            el.setAttribute("name",name);
1010                    el.setAttribute("type","java");                 
1011        }
1012        
1013        public void updateCPPCFX(String name, String procedure, String strServerLibrary, boolean keepAlive) throws PageException {
1014            checkWriteAccess();
1015            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_CFX_SETTING);
1016            
1017            if(!hasAccess) throw new SecurityException("no access to change cfx settings");
1018            
1019            // name
1020            if(StringUtil.isEmpty(name))
1021                throw new ExpressionException("name cannot be a empty value");
1022            
1023            // serverLibrary
1024            if(StringUtil.isEmpty(strServerLibrary)) throw new ExpressionException("serverLibrary cannot be a empty value");
1025            Resource serverLibrary = ResourceUtil.toResourceExisting(config, strServerLibrary);
1026            
1027            // procedure
1028            if(StringUtil.isEmpty(procedure)) throw new ExpressionException("procedure cannot be a empty value");
1029            
1030            renameOldstyleCFX();
1031            
1032            
1033            Element tags=_getRootElement("ext-tags");
1034            
1035            // Update
1036            Element[] children = ConfigWebFactory.getChildren(tags,"ext-tag");
1037            for(int i=0;i<children.length;i++) {
1038                String n=children[i].getAttribute("name");
1039                
1040                if(n!=null && n.equalsIgnoreCase(name)) {
1041                            Element el=children[i];
1042                            if(!"cpp".equalsIgnoreCase(el.getAttribute("type"))) throw new ExpressionException("there is already a java cfx tag with this name");
1043                    el.setAttribute("server-library",serverLibrary.getAbsolutePath());
1044                    el.setAttribute("procedure",procedure);
1045                    el.setAttribute("keep-alive",Caster.toString(keepAlive));
1046                    el.setAttribute("type","cpp");
1047                            return ;
1048                            }
1049                
1050            }
1051            
1052            // Insert
1053            Element el=doc.createElement("ext-tag");
1054            tags.appendChild(el);
1055            el.setAttribute("server-library",serverLibrary.getAbsolutePath());
1056            el.setAttribute("procedure",procedure);
1057            el.setAttribute("keep-alive",Caster.toString(keepAlive));
1058            el.setAttribute("name",name);
1059                    el.setAttribute("type","cpp"); 
1060            }
1061        
1062        private void renameOldstyleCFX() {
1063            
1064            Element tags=_getRootElement("ext-tags",false,true);
1065            if(tags!=null) return;
1066            tags=_getRootElement("cfx-tags",false,true);
1067            if(tags==null) return;
1068            
1069            
1070            
1071            Element newTags = _getRootElement("ext-tags");
1072            Element[] children = ConfigWebFactory.getChildren(tags,"cfx-tag");
1073            String type;
1074            // copy
1075            for(int i=0;i<children.length;i++) {
1076                Element el=doc.createElement("ext-tag");
1077                newTags.appendChild(el);
1078                type=children[i].getAttribute("type");
1079                // java
1080                if(type.equalsIgnoreCase("java")){
1081                    el.setAttribute("class",children[i].getAttribute("class"));
1082                }
1083                // c++
1084                else {
1085                    el.setAttribute("server-library",children[i].getAttribute("server-library"));
1086                    el.setAttribute("procedure",children[i].getAttribute("procedure"));
1087                    el.setAttribute("keep-alive",children[i].getAttribute("keep-alive"));
1088                    
1089                }
1090                    el.setAttribute("name",children[i].getAttribute("name"));
1091                    el.setAttribute("type",children[i].getAttribute("type"));  
1092            }
1093            
1094            // remove old
1095            for(int i=0;i<children.length;i++) {
1096                    tags.removeChild(children[i]);
1097            }
1098            tags.getParentNode().removeChild(tags);
1099            }
1100        
1101        
1102        public static boolean fixPSQ(Document doc) {
1103            
1104            Element datasources=ConfigWebFactory.getChildByName(doc.getDocumentElement(),"data-sources",false,true);
1105            if(datasources!=null && datasources.hasAttribute("preserve-single-quote")){
1106                    Boolean b=Caster.toBoolean(datasources.getAttribute("preserve-single-quote"),null);
1107                    if(b!=null)datasources.setAttribute("psq",Caster.toString(!b.booleanValue()));
1108                    datasources.removeAttribute("preserve-single-quote");
1109                    return true;
1110            }
1111            return false;
1112        }
1113    
1114        public static boolean fixS3(Document doc) {
1115            Element resources=ConfigWebFactory.getChildByName(doc.getDocumentElement(),"resources",false,true);
1116            
1117            Element[] providers = ConfigWebFactory.getChildren(resources,"resource-provider");
1118            
1119            // replace extension class with core class
1120            for(int i=0;i<providers.length;i++) {
1121                    if("s3".equalsIgnoreCase(providers[i].getAttribute("scheme"))) {
1122                            if("railo.extension.io.resource.type.s3.S3ResourceProvider".equalsIgnoreCase(providers[i].getAttribute("class"))){
1123                                    providers[i].setAttribute("class", S3ResourceProvider.class.getName());
1124                                    return true;
1125                            }
1126                            return false;
1127                    }
1128            }
1129            
1130            
1131            // FUTURE remove this part in upcoming versions
1132            // add s3 when not
1133            Element el=doc.createElement("resource-provider");
1134            el.setAttribute("scheme", "s3");
1135            el.setAttribute("class", S3ResourceProvider.class.getName());
1136            el.setAttribute("arguments", "lock-timeout:10000;");
1137            resources.appendChild(el);
1138            
1139            return true;
1140            }
1141    
1142        
1143        
1144      
1145        public void verifyCFX(String name) throws PageException {
1146            CFXTagPool pool=config.getCFXTagPool();
1147                    CustomTag ct=null;
1148                    try {
1149                            ct = pool.getCustomTag(name);
1150                    } 
1151            catch (CFXTagException e) {
1152                            throw Caster.toPageException(e);
1153                    }
1154            finally {
1155                    if(ct!=null)pool.releaseCustomTag(ct);
1156            }
1157                    
1158            }
1159        
1160    
1161    
1162            public void verifyJavaCFX(String name,String strClass) throws PageException {
1163            try {
1164                    Class clazz = ClassUtil.loadClass(config.getClassLoader(),strClass);
1165                            if(!Reflector.isInstaneOf(clazz, CustomTag.class))
1166                                    throw new ExpressionException("class ["+strClass+"] must implement interface ["+CustomTag.class.getName()+"]");
1167            } 
1168            catch (ClassException e) {
1169                    throw Caster.toPageException(e);
1170                    }
1171            
1172            if(StringUtil.startsWithIgnoreCase(name,"cfx_"))name=name.substring(4);
1173            if(StringUtil.isEmpty(name))
1174                throw new ExpressionException("class name can't be a empty value");
1175        }
1176        
1177    
1178        /**
1179         * remove a CFX Tag
1180         * @param name
1181         * @throws ExpressionException
1182         * @throws SecurityException 
1183         */
1184        public void removeCFX(String name) throws ExpressionException, SecurityException {
1185            checkWriteAccess();
1186            // check parameters
1187            if(name==null || name.length()==0)
1188                throw new ExpressionException("name for CFX Tag can be a empty value");
1189            
1190            renameOldstyleCFX();
1191            
1192            Element mappings=_getRootElement("ext-tags");
1193    
1194            Element[] children = ConfigWebFactory.getChildren(mappings,"ext-tag");
1195            for(int i=0;i<children.length;i++) {
1196                String n=children[i].getAttribute("name"); 
1197                    if(n!=null && n.equalsIgnoreCase(name)) {
1198                            mappings.removeChild(children[i]);
1199                            }
1200                }
1201        }
1202    
1203        /**
1204         * update or insert new database connection
1205         * @param name
1206         * @param clazzName
1207         * @param dsn
1208         * @param username
1209         * @param password
1210         * @param host 
1211         * @param database 
1212         * @param port 
1213         * @param connectionLimit 
1214         * @param connectionTimeout 
1215         * @param blob 
1216         * @param clob 
1217         * @param allow 
1218         * @param storage 
1219         * @param custom 
1220         * @throws ExpressionException
1221         * @throws SecurityException
1222         */
1223        public void updateDataSource(String name, String newName, String clazzName, String dsn, String username,String password,
1224                String host,String database,int port,int connectionLimit, int connectionTimeout,long metaCacheTimeout,
1225                boolean blob,boolean clob,int allow,boolean validate,boolean storage,String timezone, Struct custom) throws ExpressionException, SecurityException {
1226    
1227            checkWriteAccess();
1228            SecurityManager sm = config.getSecurityManager();
1229            short access = sm.getAccess(SecurityManager.TYPE_DATASOURCE);
1230            boolean hasAccess=true;
1231            boolean hasInsertAccess=true;
1232            int maxLength=0;
1233            
1234            if(access==SecurityManager.VALUE_YES) hasAccess=true;
1235            else if(access==SecurityManager.VALUE_NO) hasAccess=false;
1236            else if(access>=SecurityManager.VALUE_1 && access<=SecurityManager.VALUE_10){
1237                    int existingLength=getDatasourceLength(config);
1238                    maxLength=access-SecurityManager.NUMBER_OFFSET;
1239                    hasInsertAccess=maxLength>existingLength;
1240                    //print.ln("maxLength:"+maxLength);
1241                    //print.ln("existingLength:"+existingLength);
1242            }
1243            //print.ln("hasAccess:"+hasAccess);
1244            //print.ln("hasInsertAccess:"+hasInsertAccess);
1245            
1246            //boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_DATASOURCE);
1247            if(!hasAccess)
1248                throw new SecurityException("no access to update datsource connections");
1249            
1250            // check parameters
1251            if(name==null || name.length()==0)
1252                throw new ExpressionException("name can't be a empty value");
1253            
1254            try {
1255                            ClassUtil.loadInstance(clazzName);
1256                    }
1257            catch (ClassException e) {
1258                throw new ExpressionException(e.getMessage());
1259                    }
1260            
1261            Element datasources=_getRootElement("data-sources");
1262            
1263            // Update
1264            Element[] children = ConfigWebFactory.getChildren(datasources,"data-source");
1265            for(int i=0;i<children.length;i++) {
1266                String n=children[i].getAttribute("name");
1267                
1268                if(n.equalsIgnoreCase(name)) {
1269                            Element el=children[i];
1270                            if(password.equalsIgnoreCase("****************"))
1271                            password=el.getAttribute("password");
1272                        
1273                            if(!StringUtil.isEmpty(newName) && !newName.equals(name))
1274                                    el.setAttribute("name",newName);
1275                            el.setAttribute("class",clazzName);
1276                            el.setAttribute("dsn",dsn);
1277                            el.setAttribute("username",username);
1278                            el.setAttribute("password",ConfigWebFactory.encrypt(password));
1279    
1280                    el.setAttribute("host",host);
1281                    if(!StringUtil.isEmpty(timezone))el.setAttribute("timezone",timezone);
1282                    else if(el.hasAttribute("timezone")) el.removeAttribute("timezone");
1283                    el.setAttribute("database",database);
1284                    el.setAttribute("port",Caster.toString(port));
1285                    el.setAttribute("connectionLimit",Caster.toString(connectionLimit));
1286                    el.setAttribute("connectionTimeout",Caster.toString(connectionTimeout));
1287                    el.setAttribute("metaCacheTimeout",Caster.toString(metaCacheTimeout));
1288                    el.setAttribute("blob",Caster.toString(blob));
1289                    el.setAttribute("clob",Caster.toString(clob));
1290                    el.setAttribute("allow",Caster.toString(allow));
1291                    el.setAttribute("validate",Caster.toString(validate));
1292                    el.setAttribute("storage",Caster.toString(storage));
1293                    el.setAttribute("custom",toStringURLStyle(custom));
1294                    
1295                            return ;
1296                            }
1297            }
1298            
1299            if(!hasInsertAccess)
1300                throw new SecurityException("no access to add datsource connections, the maximum count of ["+maxLength+"] datasources is reached");
1301            
1302            // Insert
1303            Element el=doc.createElement("data-source");
1304            datasources.appendChild(el);
1305            if(!StringUtil.isEmpty(newName))
1306                    el.setAttribute("name",newName);
1307            else 
1308                    el.setAttribute("name",name);
1309                    el.setAttribute("class",clazzName);
1310                    el.setAttribute("dsn",dsn);
1311                    if(username.length()>0)el.setAttribute("username",username);
1312                    if(password.length()>0)el.setAttribute("password",ConfigWebFactory.encrypt(password));
1313            
1314            el.setAttribute("host",host);
1315            if(!StringUtil.isEmpty(timezone))el.setAttribute("timezone",timezone);
1316            el.setAttribute("database",database);
1317            if(port>-1)el.setAttribute("port",Caster.toString(port));
1318            if(connectionLimit>-1)el.setAttribute("connectionLimit",Caster.toString(connectionLimit));
1319            if(connectionTimeout>-1)el.setAttribute("connectionTimeout",Caster.toString(connectionTimeout));
1320            if(metaCacheTimeout>-1)el.setAttribute("metaCacheTimeout",Caster.toString(metaCacheTimeout));
1321            
1322            
1323            
1324            el.setAttribute("blob",Caster.toString(blob));
1325            el.setAttribute("clob",Caster.toString(clob));
1326            el.setAttribute("validate",Caster.toString(validate));
1327            el.setAttribute("storage",Caster.toString(storage));
1328            if(allow>-1)el.setAttribute("allow",Caster.toString(allow));
1329            el.setAttribute("custom",toStringURLStyle(custom));
1330            /*
1331                        String host,String database,int port,String connectionLimit, String connectionTimeout,
1332                boolean blob,boolean clob,int allow,Struct custom
1333            );
1334            */
1335        }
1336        
1337    
1338            public void updateGatewayEntry(String id,String className, String cfcPath, String listenerCfcPath,int startupMode,Struct custom, boolean readOnly) throws PageException {
1339                    
1340                    checkWriteAccess();
1341            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManagerImpl.TYPE_GATEWAY);
1342            
1343            if(!hasAccess)
1344                throw new SecurityException("no access to update gateway entry");
1345            
1346            
1347            // check parameters
1348            id=id.trim();
1349            if(StringUtil.isEmpty(id))
1350                throw new ExpressionException("id can't be a empty value");
1351            
1352            if(StringUtil.isEmpty(className) && StringUtil.isEmpty(cfcPath))
1353                    throw new ExpressionException("you must define className or cfcPath");
1354            
1355            try {
1356                    if(!StringUtil.isEmpty(className)){
1357                            ClassUtil.loadClass(className);
1358                    }
1359                    }
1360            catch (ClassException e) {
1361                throw new ExpressionException(e.getMessage());
1362                    }
1363            
1364            Element parent=_getRootElement("gateways");
1365            
1366            // Update
1367            Element[] children = ConfigWebFactory.getChildren(parent,"gateway");
1368            for(int i=0;i<children.length;i++) {
1369                String n=children[i].getAttribute("id");
1370                Element el=children[i];
1371                if(n.equalsIgnoreCase(id)) {
1372                    el.setAttribute("class",className);
1373                    el.setAttribute("cfc-path",cfcPath);
1374                    el.setAttribute("listener-cfc-path",listenerCfcPath);
1375                    el.setAttribute("startup-mode",GatewayEntryImpl.toStartup(startupMode, "automatic"));
1376                    el.setAttribute("custom",toStringURLStyle(custom));
1377                            el.setAttribute("read-only",Caster.toString(readOnly));
1378                            return;
1379                            }
1380              
1381            }
1382            // Insert
1383            Element el=doc.createElement("gateway");
1384            parent.appendChild(el);
1385            el.setAttribute("id",id);
1386            el.setAttribute("cfc-path",cfcPath);
1387            el.setAttribute("listener-cfc-path",listenerCfcPath);
1388                el.setAttribute("startup-mode",GatewayEntryImpl.toStartup(startupMode, "automatic"));
1389                el.setAttribute("class",className);
1390                    el.setAttribute("custom",toStringURLStyle(custom));
1391                    el.setAttribute("read-only",Caster.toString(readOnly));
1392            
1393        }
1394    
1395            public void updateCacheConnection(String name, String classname,int _default, Struct custom,boolean readOnly,boolean storage) throws PageException {
1396            checkWriteAccess();
1397            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManagerImpl.TYPE_CACHE);
1398                    if(!hasAccess)
1399                throw new SecurityException("no access to update cache connection");
1400            
1401            
1402            // check parameters
1403            name=name.trim();
1404            if(StringUtil.isEmpty(name))
1405                throw new ExpressionException("name can't be a empty value");
1406            //else if(name.equals("template") || name.equals("object"))
1407                    //throw new ExpressionException("name ["+name+"] is not allowed for a cache connection, the following names are reserved words [object,template]");     
1408            
1409            try {
1410                    Class clazz = ClassUtil.loadClass(config.getClassLoader(),classname);
1411                            if(!Reflector.isInstaneOf(clazz, Cache.class))
1412                                    throw new ExpressionException("class ["+clazz.getName()+"] is not of type ["+Cache.class.getName()+"]");
1413                    }
1414            catch (ClassException e) {
1415                throw new ExpressionException(e.getMessage());
1416                    }
1417            
1418            Element parent=_getRootElement("cache");
1419    
1420            if(name.equalsIgnoreCase(parent.getAttribute("default-template")))
1421                    parent.removeAttribute("default-template");
1422            if(name.equalsIgnoreCase(parent.getAttribute("default-object")))
1423                    parent.removeAttribute("default-object");
1424            if(name.equalsIgnoreCase(parent.getAttribute("default-query")))
1425                    parent.removeAttribute("default-query");
1426            if(name.equalsIgnoreCase(parent.getAttribute("default-resource")))
1427                    parent.removeAttribute("default-resource");
1428            if(name.equalsIgnoreCase(parent.getAttribute("default-function")))
1429                    parent.removeAttribute("default-function");
1430            
1431            
1432            if(_default==ConfigImpl.CACHE_DEFAULT_OBJECT){
1433                    parent.setAttribute("default-object",name);
1434            }
1435            else if(_default==ConfigImpl.CACHE_DEFAULT_TEMPLATE){
1436                    parent.setAttribute("default-template",name);
1437            }
1438            else if(_default==ConfigImpl.CACHE_DEFAULT_QUERY){
1439                    parent.setAttribute("default-query",name);
1440            }
1441            else if(_default==ConfigImpl.CACHE_DEFAULT_RESOURCE){
1442                    parent.setAttribute("default-resource",name);
1443            }
1444            else if(_default==ConfigImpl.CACHE_DEFAULT_FUNCTION){
1445                    parent.setAttribute("default-function",name);
1446            }
1447            
1448            // Update
1449            //boolean isUpdate=false;
1450            Element[] children = ConfigWebFactory.getChildren(parent,"connection");
1451            for(int i=0;i<children.length;i++) {
1452                String n=children[i].getAttribute("name");
1453                Element el=children[i];
1454                if(n.equalsIgnoreCase(name)) {
1455                    el.setAttribute("class",classname);
1456                            //el.setAttribute("default",Caster.toString(_default));
1457                            el.setAttribute("custom",toStringURLStyle(custom));
1458                            el.setAttribute("read-only",Caster.toString(readOnly));
1459                            el.setAttribute("storage",Caster.toString(storage));
1460                            return;
1461                            }
1462              
1463            }
1464            
1465            // Insert
1466            Element el=doc.createElement("connection");
1467            parent.appendChild(el);
1468            el.setAttribute("name",name);
1469                    el.setAttribute("class",classname);
1470                    //el.setAttribute("default",Caster.toString(_default));
1471                    el.setAttribute("custom",toStringURLStyle(custom));
1472                    el.setAttribute("read-only",Caster.toString(readOnly));
1473                    el.setAttribute("storage",Caster.toString(storage));
1474            
1475        }
1476            
1477            public void removeCacheDefaultConnection(int type) throws PageException {
1478            checkWriteAccess();
1479            
1480            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManagerImpl.TYPE_CACHE);
1481            if(!hasAccess)
1482                throw new SecurityException("no access to update cache connections");
1483            
1484            Element parent=_getRootElement("cache");
1485            if(type==ConfigImpl.CACHE_DEFAULT_OBJECT){
1486                    parent.removeAttribute("default-object");
1487            }
1488            else if(type==ConfigImpl.CACHE_DEFAULT_TEMPLATE){
1489                    parent.removeAttribute("default-template");
1490            }
1491            else if(type==ConfigImpl.CACHE_DEFAULT_QUERY){
1492                    parent.removeAttribute("default-query");
1493            }
1494            else if(type==ConfigImpl.CACHE_DEFAULT_RESOURCE){
1495                    parent.removeAttribute("default-resource");
1496            }
1497            else if(type==ConfigImpl.CACHE_DEFAULT_FUNCTION){
1498                    parent.removeAttribute("default-function");
1499            }
1500        }
1501            
1502            public void updateCacheDefaultConnection(int type,String name) throws PageException {
1503            checkWriteAccess();
1504            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManagerImpl.TYPE_CACHE);
1505            
1506            if(!hasAccess)
1507                throw new SecurityException("no access to update cache default connections");
1508            
1509            Element parent=_getRootElement("cache");
1510            if(type==ConfigImpl.CACHE_DEFAULT_OBJECT){
1511                    parent.setAttribute("default-object", name);
1512            }
1513            else if(type==ConfigImpl.CACHE_DEFAULT_TEMPLATE){
1514                    parent.setAttribute("default-template", name);
1515            }
1516            else if(type==ConfigImpl.CACHE_DEFAULT_QUERY){
1517                    parent.setAttribute("default-query", name);
1518            }
1519            else if(type==ConfigImpl.CACHE_DEFAULT_RESOURCE){
1520                    parent.setAttribute("default-resource", name);
1521            }
1522            else if(type==ConfigImpl.CACHE_DEFAULT_FUNCTION){
1523                    parent.setAttribute("default-function", name);
1524            }
1525        }
1526            
1527        public void removeResourceProvider(Class clazz) throws PageException {
1528            checkWriteAccess();
1529            SecurityManager sm = config.getSecurityManager();
1530            short access = sm.getAccess(SecurityManager.TYPE_FILE);
1531            boolean hasAccess=access==SecurityManager.VALUE_YES;
1532            
1533            String className=clazz.getName();
1534            
1535            if(!hasAccess)
1536                throw new SecurityException("no access to remove resources");
1537            
1538            Element parent=_getRootElement("resources");
1539            
1540            // remove
1541            Element[] children = ConfigWebFactory.getChildren(parent,"resource-provider");
1542            for(int i=0;i<children.length;i++) {
1543                String cn=children[i].getAttribute("class");
1544                if(cn.equalsIgnoreCase(className)) {
1545                    parent.removeChild(children[i]);                
1546                            break;
1547                            }
1548            }
1549            }       
1550        
1551        public void updateResourceProvider(String scheme, Class clazz,Struct arguments) throws PageException {
1552            updateResourceProvider(scheme, clazz, toStringCSSStyle(arguments));
1553        }
1554    
1555            public void updateResourceProvider(String scheme, Class clazz,String arguments) throws PageException {
1556            checkWriteAccess();
1557            SecurityManager sm = config.getSecurityManager();
1558            short access = sm.getAccess(SecurityManager.TYPE_FILE);
1559            boolean hasAccess=access==SecurityManager.VALUE_YES;
1560            
1561            String className=clazz.getName();
1562            
1563            if(!hasAccess)
1564                throw new SecurityException("no access to update resources");
1565            
1566            // check parameters
1567            if(StringUtil.isEmpty(scheme))throw new ExpressionException("scheme can't be a empty value");
1568            
1569            Element parent=_getRootElement("resources");
1570            
1571            // Update
1572            Element[] children = ConfigWebFactory.getChildren(parent,"resource-provider");
1573            for(int i=0;i<children.length;i++) {
1574                String cn=children[i].getAttribute("class");
1575                if(cn.equalsIgnoreCase(className)) {
1576                            Element el=children[i];
1577                            el.setAttribute("scheme",scheme);
1578                            el.setAttribute("arguments",arguments);                
1579                            return ;
1580                            }
1581            }
1582            
1583            // Insert
1584            Element el=doc.createElement("resource-provider");
1585            parent.appendChild(el);
1586                    el.setAttribute("scheme",scheme);
1587                    el.setAttribute("arguments",arguments);  
1588                    el.setAttribute("class",className);
1589            }       
1590            
1591            public void updateDefaultResourceProvider(Class clazz, String arguments) throws PageException {
1592            checkWriteAccess();
1593            SecurityManager sm = config.getSecurityManager();
1594            short access = sm.getAccess(SecurityManager.TYPE_FILE);
1595            boolean hasAccess=access==SecurityManager.VALUE_YES;
1596            
1597            String className=clazz.getName();
1598            
1599            if(!hasAccess)
1600                throw new SecurityException("no access to update resources");
1601            
1602            Element parent=_getRootElement("resources");
1603            
1604            // Update
1605            Element[] children = ConfigWebFactory.getChildren(parent,"default-resource-provider");
1606            for(int i=0;i<children.length;i++) {
1607                Element el=children[i];
1608                    el.setAttribute("arguments",arguments);                
1609                    return;
1610            }
1611            
1612            // Insert
1613            Element el=doc.createElement("default-resource-provider");
1614            parent.appendChild(el);
1615                    el.setAttribute("arguments",arguments);  
1616                    el.setAttribute("class",className);
1617            }
1618    
1619        private int getDatasourceLength(ConfigImpl config) {
1620            Map ds = config.getDataSourcesAsMap();
1621            Iterator it = ds.keySet().iterator();
1622            int len=0;
1623            
1624            while(it.hasNext()) {
1625                    if(!((DataSource)ds.get(it.next())).isReadOnly())len++;
1626            }
1627                    return len;
1628            }
1629    
1630    
1631            private static String toStringURLStyle(Struct sct) {
1632            Iterator<Entry<Key, Object>> it = sct.entryIterator();
1633                    Entry<Key, Object> e;
1634            StringBuffer rtn=new StringBuffer();
1635            while(it.hasNext()) {
1636                e = it.next();
1637                if(rtn.length()>0)rtn.append('&');
1638                rtn.append(URLEncoder.encode(e.getKey().getString()));
1639                rtn.append('=');
1640                rtn.append(URLEncoder.encode(Caster.toString(e.getValue(),"")));
1641            }
1642            return rtn.toString();
1643        }
1644    
1645            private static String toStringCSSStyle(Struct sct) {
1646            //Collection.Key[] keys = sct.keys();
1647            StringBuffer rtn=new StringBuffer();
1648            Iterator<Entry<Key, Object>> it = sct.entryIterator();
1649                    Entry<Key, Object> e;
1650            
1651                    while(it.hasNext()) {
1652                            e = it.next();
1653                if(rtn.length()>0)rtn.append(';');
1654                rtn.append(encode(e.getKey().getString()));
1655                rtn.append(':');
1656                rtn.append(encode(Caster.toString(e.getValue(),"")));
1657            }
1658            return rtn.toString();
1659        }
1660    
1661        private static String encode(String str) {
1662                    try {
1663                            return URLEncodedFormat.invoke(str, "UTF-8",false);
1664                    } catch (PageException e) {
1665                            return URLEncoder.encode(str);
1666                    }
1667            }
1668    
1669    
1670            public Query getResourceProviders() throws PageException {
1671            checkReadAccess();
1672            // check parameters
1673            Element parent=_getRootElement("resources");
1674            Element[] elProviders = ConfigWebFactory.getChildren(parent,"resource-provider");
1675            Element[] elDefaultProviders = ConfigWebFactory.getChildren(parent,"default-resource-provider");
1676            ResourceProvider[] providers = config.getResourceProviders();
1677            ResourceProvider defaultProvider = config.getDefaultResourceProvider();
1678                    
1679            Query qry=new QueryImpl(new String[]{"support","scheme","caseSensitive","default","class","arguments"},elProviders.length+elDefaultProviders.length,"resourceproviders");
1680            int row=1;
1681            for(int i=0;i<elDefaultProviders.length;i++) {
1682                    getResourceProviders(new ResourceProvider[]{defaultProvider},qry,elDefaultProviders[i],row++,Boolean.TRUE);
1683                }
1684            for(int i=0;i<elProviders.length;i++) {
1685                    getResourceProviders(providers,qry,elProviders[i],row++,Boolean.FALSE);
1686                }
1687            return qry;
1688        }
1689        
1690        private void getResourceProviders(ResourceProvider[] providers,Query qry,Element p, int row,Boolean def) throws PageException {
1691            Array support=new ArrayImpl();
1692                String clazz=p.getAttribute("class");
1693                    qry.setAt("scheme",row,p.getAttribute("scheme"));
1694                    qry.setAt("arguments",row,p.getAttribute("arguments"));
1695                    qry.setAt("class",row,clazz);
1696                    for(int i=0;i<providers.length;i++) {
1697                            if(providers[i].getClass().getName().equals(clazz)){
1698                                    if(providers[i].isAttributesSupported())support.append("attributes");
1699                        if(providers[i].isModeSupported())support.append("mode");
1700                        qry.setAt("support",row,ListUtil.arrayToList(support, ","));
1701                        qry.setAt("scheme",row,providers[i].getScheme());
1702                        qry.setAt("caseSensitive",row,Caster.toBoolean(providers[i].isCaseSensitive()));
1703                        qry.setAt("default",row,def);
1704                                    break;
1705                            }
1706                    }
1707            }
1708    
1709    
1710            /**
1711         * remove a DataSource Connection
1712         * @param name
1713         * @throws ExpressionException
1714         * @throws SecurityException 
1715         */
1716        public void removeDataSource(String name) throws ExpressionException, SecurityException {
1717            checkWriteAccess();
1718            // check parameters
1719            if(name==null || name.length()==0)
1720                throw new ExpressionException("name for Datasource Connection can be a empty value");
1721            
1722    
1723            Element datasources=_getRootElement("data-sources");
1724    
1725            Element[] children = ConfigWebFactory.getChildren(datasources,"data-source");
1726            for(int i=0;i<children.length;i++) {
1727                String n=children[i].getAttribute("name"); 
1728                    if(n!=null && n.equalsIgnoreCase(name)) {
1729                      datasources.removeChild(children[i]);
1730                            }
1731                }
1732        }
1733    
1734            public void removeCacheConnection(String name) throws ExpressionException, SecurityException {
1735                    checkWriteAccess();
1736                    
1737                    boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManagerImpl.TYPE_CACHE);
1738                    if(!hasAccess)
1739                throw new SecurityException("no access to remove cache connection");
1740            
1741                    
1742            // check parameters
1743            if(StringUtil.isEmpty(name))
1744                throw new ExpressionException("name for Cache Connection can be a empty value");
1745            
1746            Element parent=_getRootElement("cache");
1747            
1748            // remove default flag
1749            if(name.equalsIgnoreCase(parent.getAttribute("default-object")))
1750                    parent.removeAttribute("default-object");
1751            if(name.equalsIgnoreCase(parent.getAttribute("default-template")))
1752                    parent.removeAttribute("default-template");
1753            if(name.equalsIgnoreCase(parent.getAttribute("default-query")))
1754                    parent.removeAttribute("default-query");
1755            if(name.equalsIgnoreCase(parent.getAttribute("default-resource")))
1756                    parent.removeAttribute("default-resource");
1757            
1758            // remove element
1759            Element[] children = ConfigWebFactory.getChildren(parent,"connection");
1760            for(int i=0;i<children.length;i++) {
1761                String n=children[i].getAttribute("name"); 
1762                    if(n!=null && n.equalsIgnoreCase(name)) {
1763                            Map<String, CacheConnection> conns = config.getCacheConnections();
1764                            CacheConnection cc= conns.get(n.toLowerCase());
1765                            if(cc!=null)Util.removeEL(config instanceof ConfigWeb?(ConfigWeb)config:null,cc);
1766                      parent.removeChild(children[i]);
1767                            }
1768                }
1769            
1770            }
1771            
1772    
1773            public void removeCacheGatewayEntry(String name) throws PageException {
1774                    checkWriteAccess();
1775            
1776                    boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManagerImpl.TYPE_GATEWAY);
1777            if(!hasAccess)
1778                throw new SecurityException("no access to remove gateway entry");
1779            
1780            if(StringUtil.isEmpty(name))
1781                throw new ExpressionException("name for Gateway Id can be a empty value");
1782            
1783            Element parent=_getRootElement("gateways");
1784            
1785            // remove element
1786            Element[] children = ConfigWebFactory.getChildren(parent,"gateway");
1787            for(int i=0;i<children.length;i++) {
1788                String n=children[i].getAttribute("id"); 
1789                    if(n!=null && n.equalsIgnoreCase(name)) {
1790                            Map conns = ((ConfigWebImpl)config).getGatewayEngine().getEntries();
1791                            GatewayEntry ge=(GatewayEntry) conns.get(n);
1792                            if(ge!=null){
1793                                    ((ConfigWebImpl)config).getGatewayEngine().remove(ge);
1794                            }
1795                            parent.removeChild(children[i]);
1796                            }
1797                }
1798            }
1799    
1800            
1801            
1802        public void removeRemoteClient(String url) throws ExpressionException, SecurityException {
1803            checkWriteAccess();
1804            
1805            // SNSN
1806            
1807            
1808            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManagerImpl.TYPE_REMOTE);
1809            if(!hasAccess)
1810                throw new SecurityException("no access to remove remote client settings");
1811            
1812            
1813            
1814            // check parameters
1815            if(StringUtil.isEmpty(url))
1816                throw new ExpressionException("url for Remote Client can be a empty value");
1817            
1818    
1819            Element clients=_getRootElement("remote-clients");
1820    
1821            Element[] children = ConfigWebFactory.getChildren(clients,"remote-client");
1822            for(int i=0;i<children.length;i++) {
1823                String n=children[i].getAttribute("url"); 
1824                    if(n!=null && n.equalsIgnoreCase(url)) {
1825                      clients.removeChild(children[i]);
1826                            }
1827                }
1828        }
1829        
1830        /**
1831         *  update PSQ State
1832         * @param psq Preserver Single Quote
1833         * @throws SecurityException
1834         */
1835        public void updatePSQ(Boolean psq) throws SecurityException {
1836            checkWriteAccess();
1837            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_DATASOURCE);
1838            
1839            if(!hasAccess) throw new SecurityException("no access to update datsource connections");
1840            
1841            Element datasources=_getRootElement("data-sources");
1842            datasources.setAttribute("psq",Caster.toString(psq,""));
1843            if(datasources.hasAttribute("preserve-single-quote"))
1844                    datasources.removeAttribute("preserve-single-quote");
1845        }
1846    
1847    
1848            public void updateInspectTemplate(String str) throws SecurityException {
1849                    checkWriteAccess();
1850            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
1851            
1852            if(!hasAccess) throw new SecurityException("no access to update");
1853            
1854            Element datasources=_getRootElement("java");
1855            datasources.setAttribute("inspect-template",str);
1856    
1857            }
1858        
1859        
1860        /**
1861         * sets the scope cascading type
1862         * @param type (ServletConfigImpl.SCOPE_XYZ)
1863         * @throws SecurityException
1864         */ 
1865        public void updateScopeCascadingType(String type) throws SecurityException {
1866            checkWriteAccess();
1867            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
1868            
1869            if(!hasAccess) throw new SecurityException("no access to update scope setting");
1870            
1871            
1872            Element scope=_getRootElement("scope");
1873            if(type.equalsIgnoreCase("strict"))        scope.setAttribute("cascading","strict");
1874            else if(type.equalsIgnoreCase("small"))    scope.setAttribute("cascading","small");
1875            else if(type.equalsIgnoreCase("standard")) scope.setAttribute("cascading","standard");
1876            else                                       scope.setAttribute("cascading","standard");
1877            
1878        }
1879        
1880        /**
1881         * sets the scope cascading type
1882         * @param type (ServletConfigImpl.SCOPE_XYZ)
1883         * @throws SecurityException
1884         */ 
1885        public void updateScopeCascadingType(short type) throws SecurityException {
1886            checkWriteAccess();
1887            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
1888            if(!hasAccess)
1889                throw new SecurityException("no access to update scope setting");
1890            
1891            //railo.print.ln("********........type:"+type);
1892            Element scope=_getRootElement("scope");
1893            if(type==ConfigWeb.SCOPE_STRICT) scope.setAttribute("cascading","strict");
1894            else if(type==ConfigWeb.SCOPE_SMALL) scope.setAttribute("cascading","small");
1895            else if(type==ConfigWeb.SCOPE_STANDARD) scope.setAttribute("cascading","standard");
1896            
1897        }
1898        
1899        /**
1900         * sets if allowed implicid query call
1901         * @param allow
1902         * @throws SecurityException
1903         */
1904        public void updateAllowImplicidQueryCall(Boolean allow) throws SecurityException {
1905            checkWriteAccess();
1906            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
1907            
1908            if(!hasAccess) throw new SecurityException("no access to update scope setting");
1909            
1910            Element scope=_getRootElement("scope");
1911            scope.setAttribute("cascade-to-resultset",Caster.toString(allow,""));
1912            
1913        }
1914        
1915        public void updateMergeFormAndUrl(Boolean merge) throws SecurityException {
1916            checkWriteAccess();
1917            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
1918            
1919            if(!hasAccess) throw new SecurityException("no access to update scope setting");
1920            
1921            Element scope=_getRootElement("scope");
1922            scope.setAttribute("merge-url-form",Caster.toString(merge,""));
1923            
1924        }
1925        
1926        /**
1927         * updates request timeout value
1928         * @param span
1929         * @throws SecurityException
1930         * @throws ApplicationException 
1931         */
1932        public void updateRequestTimeout(TimeSpan span) throws SecurityException, ApplicationException {
1933            checkWriteAccess();
1934            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
1935            
1936            if(!hasAccess) throw new SecurityException("no access to update scope setting");
1937            
1938            Element scope=_getRootElement("scope");
1939            
1940            Element application=_getRootElement("application");
1941            if(span!=null){
1942                    if(span.getMillis()<=0)
1943                            throw new ApplicationException("value must be a positive number");
1944                    application.setAttribute("requesttimeout",span.getDay()+","+span.getHour()+","+span.getMinute()+","+span.getSecond());
1945            }
1946            else application.removeAttribute("requesttimeout");
1947            
1948            // remove deprecated attribute
1949            if(scope.hasAttribute("requesttimeout"))
1950                    scope.removeAttribute("requesttimeout");
1951        }
1952        
1953        /**
1954         * updates session timeout value
1955         * @param span
1956         * @throws SecurityException
1957         */
1958        public void updateSessionTimeout(TimeSpan span) throws SecurityException {
1959            checkWriteAccess();
1960            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
1961            
1962            if(!hasAccess) throw new SecurityException("no access to update scope setting");
1963            
1964            Element scope=_getRootElement("scope");
1965            if(span!=null)scope.setAttribute("sessiontimeout",span.getDay()+","+span.getHour()+","+span.getMinute()+","+span.getSecond());
1966            else scope.removeAttribute("sessiontimeout");
1967        }
1968        
1969        /**
1970         * updates session timeout value
1971         * @param span
1972         * @throws SecurityException
1973         */
1974        public void updateClientTimeout(TimeSpan span) throws SecurityException {
1975            checkWriteAccess();
1976            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
1977            
1978            if(!hasAccess) throw new SecurityException("no access to update scope setting");
1979            
1980            Element scope=_getRootElement("scope");
1981            if(span!=null)scope.setAttribute("clienttimeout",span.getDay()+","+span.getHour()+","+span.getMinute()+","+span.getSecond());
1982            else scope.removeAttribute("clienttimeout");
1983            
1984            // deprecated
1985            if(scope.hasAttribute("client-max-age"))scope.removeAttribute("client-max-age");
1986           
1987            
1988        }
1989        
1990    
1991        public void updateCFMLWriterType(String writerType) throws SecurityException, ApplicationException {
1992            checkWriteAccess();
1993            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
1994            if(!hasAccess) throw new SecurityException("no access to update scope setting");
1995            writerType=writerType.trim();
1996            if(!"white-space".equalsIgnoreCase(writerType) && 
1997                            !"white-space-pref".equalsIgnoreCase(writerType) && 
1998                            !"regular".equalsIgnoreCase(writerType))
1999                    throw new ApplicationException("invalid writer type defintion ["+writerType+"], valid types are [white-space, white-space-pref, regular]");
2000            
2001            Element scope=_getRootElement("setting");
2002            scope.setAttribute("cfml-writer",writerType.toLowerCase());
2003        } 
2004    
2005        /*public void updateSuppressWhitespace(Boolean value) throws SecurityException {
2006            checkWriteAccess();
2007            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2008            
2009            if(!hasAccess) throw new SecurityException("no access to update scope setting");
2010            
2011            Element scope=_getRootElement("setting");
2012            scope.setAttribute("suppress-whitespace",Caster.toString(value,""));
2013        }*/
2014        
2015        public void updateSuppressContent(Boolean value) throws SecurityException {
2016            checkWriteAccess();
2017            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2018            
2019            if(!hasAccess) throw new SecurityException("no access to update scope setting");
2020            
2021            Element scope=_getRootElement("setting");
2022            scope.setAttribute("suppress-content",Caster.toString(value,""));
2023        }
2024        
2025        public void updateShowVersion(Boolean value) throws SecurityException {
2026            checkWriteAccess();
2027            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2028            
2029            if(!hasAccess) throw new SecurityException("no access to update scope setting");
2030            
2031            Element scope=_getRootElement("setting");
2032            scope.setAttribute("show-version",Caster.toString(value,""));
2033        }
2034        
2035        public void updateAllowCompression(Boolean value) throws SecurityException {
2036            checkWriteAccess();
2037            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2038            
2039            if(!hasAccess) throw new SecurityException("no access to update scope setting");
2040            
2041            Element scope=_getRootElement("setting");
2042            scope.setAttribute("allow-compression",Caster.toString(value,""));
2043        }
2044        
2045        public void updateContentLength(Boolean value) throws SecurityException {
2046            checkWriteAccess();
2047            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2048            
2049            if(!hasAccess) throw new SecurityException("no access to update scope setting");
2050            
2051            Element scope=_getRootElement("setting");
2052            scope.setAttribute("content-length",Caster.toString(value,""));
2053        }
2054        
2055    
2056            public void updateBufferOutput(Boolean value) throws SecurityException {
2057                    checkWriteAccess();
2058            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2059            
2060            if(!hasAccess) throw new SecurityException("no access to update scope setting");
2061            
2062            Element scope=_getRootElement("setting");
2063            scope.setAttribute("buffer-output",Caster.toString(value,""));
2064            }
2065        
2066        /**
2067         * updates request timeout value
2068         * @param span
2069         * @throws SecurityException
2070         */
2071        public void updateApplicationTimeout(TimeSpan span) throws SecurityException {
2072            checkWriteAccess();
2073            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2074            
2075            if(!hasAccess) throw new SecurityException("no access to update scope setting");
2076            
2077            Element scope=_getRootElement("scope");
2078            if(span!=null)scope.setAttribute("applicationtimeout",span.getDay()+","+span.getHour()+","+span.getMinute()+","+span.getSecond());
2079            else scope.removeAttribute("applicationtimeout");
2080        }
2081    
2082        public void updateApplicationListener(String type,String mode) throws SecurityException {
2083            checkWriteAccess();
2084            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2085            
2086            if(!hasAccess) throw new SecurityException("no access to update listener type");
2087            
2088            Element scope=_getRootElement("application");
2089            scope.setAttribute("listener-type",type.toLowerCase().trim());
2090            scope.setAttribute("listener-mode",mode.toLowerCase().trim());
2091        }
2092        
2093        public void updateProxy(boolean enabled,String server, int port, String username, String password) throws SecurityException {
2094            checkWriteAccess();
2095            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2096            
2097            if(!hasAccess) throw new SecurityException("no access to update listener type");
2098            
2099            Element proxy=_getRootElement("proxy");
2100            proxy.setAttribute("enabled",Caster.toString(enabled));
2101            if(!StringUtil.isEmpty(server))         proxy.setAttribute("server",server);
2102            if(port>0)                                                   proxy.setAttribute("port",Caster.toString(port));
2103            if(!StringUtil.isEmpty(username))       proxy.setAttribute("username",username);
2104            if(!StringUtil.isEmpty(password))       proxy.setAttribute("password",password);
2105        }
2106        
2107        /*public void removeProxy() throws SecurityException {
2108            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2109            if(!hasAccess) throw new SecurityException("no access to remove proxy settings");
2110            
2111            Element proxy=_getRootElement("proxy");
2112            proxy.removeAttribute("server");
2113            proxy.removeAttribute("port");
2114            proxy.removeAttribute("username");
2115            proxy.removeAttribute("password");
2116        }*/
2117        
2118        /**
2119         * enable or desable session management
2120         * @param sessionManagement
2121         * @throws SecurityException
2122         */
2123        public void updateSessionManagement(Boolean sessionManagement) throws SecurityException {
2124            checkWriteAccess();
2125            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2126            
2127            if(!hasAccess)
2128                throw new SecurityException("no access to update scope setting");
2129            
2130            Element scope=_getRootElement("scope");
2131            scope.setAttribute("sessionmanagement",Caster.toString(sessionManagement,""));
2132        }
2133        
2134        /**
2135         * enable or desable client management
2136         * @param clientManagement
2137         * @throws SecurityException
2138         */
2139        public void updateClientManagement(Boolean clientManagement) throws SecurityException {
2140            checkWriteAccess();
2141            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2142            
2143            if(!hasAccess)
2144                throw new SecurityException("no access to update scope setting");
2145            
2146            Element scope=_getRootElement("scope");
2147            scope.setAttribute("clientmanagement",Caster.toString(clientManagement,""));
2148        }
2149        
2150        /**
2151         * set if client cookies are enabled or not
2152         * @param clientCookies
2153         * @throws SecurityException
2154         */
2155        public void updateClientCookies(Boolean clientCookies) throws SecurityException {
2156            checkWriteAccess();
2157            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2158            if(!hasAccess)
2159                throw new SecurityException("no access to update scope setting");
2160            
2161            Element scope=_getRootElement("scope");
2162            scope.setAttribute("setclientcookies",Caster.toString(clientCookies,""));
2163        }
2164        
2165        /**
2166         * set if domain cookies are enabled or not
2167         * @param domainCookies
2168         * @throws SecurityException
2169         */
2170        public void updateDomaincookies(Boolean domainCookies) throws SecurityException {
2171            checkWriteAccess();
2172            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2173            if(!hasAccess)
2174                throw new SecurityException("no access to update scope setting");
2175            
2176            Element scope=_getRootElement("scope");
2177            scope.setAttribute("setdomaincookies",Caster.toString(domainCookies,""));
2178        }
2179        
2180        /**
2181         * update the locale
2182         * @param locale
2183         * @throws SecurityException
2184         */
2185        public void updateLocale(String locale) throws SecurityException {
2186            checkWriteAccess();
2187            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2188            if(!hasAccess)
2189                throw new SecurityException("no access to update regional setting");
2190            
2191            Element scope=_getRootElement("regional");
2192            scope.setAttribute("locale",locale.trim());
2193        }
2194    
2195        public void updateMonitorEnabled(boolean updateMonitorEnabled) throws SecurityException {
2196            checkWriteAccess();
2197            
2198            Element scope=_getRootElement("monitoring");
2199            scope.setAttribute("enabled",Caster.toString(updateMonitorEnabled));
2200        }
2201        
2202        
2203        
2204        public void updateScriptProtect(String strScriptProtect) throws SecurityException {
2205            checkWriteAccess();
2206            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2207            if(!hasAccess)
2208                throw new SecurityException("no access to update script protect");
2209            
2210            Element scope=_getRootElement("application");
2211            scope.setAttribute("script-protect",strScriptProtect.trim());
2212        }
2213        
2214        public void updateAllowURLRequestTimeout(Boolean allowURLRequestTimeout) throws SecurityException {
2215            checkWriteAccess();
2216            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2217            if(!hasAccess)
2218                throw new SecurityException("no access to update AllowURLRequestTimeout");
2219            
2220            Element scope=_getRootElement("application");
2221            scope.setAttribute("allow-url-requesttimeout",Caster.toString(allowURLRequestTimeout,""));
2222        }
2223        
2224        
2225        public void updateScriptProtect(int scriptProtect) throws SecurityException { 
2226            updateScriptProtect(AppListenerUtil.translateScriptProtect(scriptProtect));
2227        }
2228        
2229        /**
2230         * update the timeZone
2231         * @param timeZone
2232         * @throws SecurityException
2233         */
2234        public void updateTimeZone(String timeZone) throws SecurityException {
2235            checkWriteAccess();
2236            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2237            if(!hasAccess)
2238                throw new SecurityException("no access to update regional setting");
2239            
2240            Element regional=_getRootElement("regional");
2241            regional.setAttribute("timezone",timeZone.trim());
2242            
2243        }
2244    
2245        /**
2246         * update the timeServer
2247         * @param timeServer
2248         * @param useTimeServer 
2249         * @throws PageException 
2250         */
2251        public void updateTimeServer(String timeServer, Boolean useTimeServer) throws PageException {
2252            checkWriteAccess();
2253           if(useTimeServer!=null && useTimeServer.booleanValue() && !StringUtil.isEmpty(timeServer,true)) {
2254                try {
2255                    new NtpClient(timeServer).getOffset();
2256                } catch (IOException e) {
2257                    throw new ExpressionException("invalid timeserver (NTP) ["+timeServer+"] ");
2258                }
2259           }
2260            
2261           boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2262           if(!hasAccess)
2263                throw new SecurityException("no access to update regional setting");
2264            
2265            Element scope=_getRootElement("regional");
2266            scope.setAttribute("timeserver",timeServer.trim());
2267            if(useTimeServer!=null)scope.setAttribute("use-timeserver",Caster.toString(useTimeServer));
2268            else scope.removeAttribute("use-timeserver");
2269        }
2270        
2271        /**
2272         * update the baseComponent
2273         * @param baseComponent
2274         * @throws SecurityException
2275         */
2276        public void updateBaseComponent(String baseComponent) throws SecurityException {
2277            checkWriteAccess();
2278            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2279            if(!hasAccess)
2280                throw new SecurityException("no access to update component setting");
2281            //config.resetBaseComponentPage();
2282            Element scope=_getRootElement("component");
2283            //if(baseComponent.trim().length()>0)
2284                    scope.setAttribute("base",baseComponent);
2285        }
2286        
2287        
2288    
2289            public void updateComponentDeepSearch(Boolean deepSearch) throws SecurityException {
2290                    checkWriteAccess();
2291                boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2292                if(!hasAccess)
2293                    throw new SecurityException("no access to update component setting");
2294                //config.resetBaseComponentPage();
2295                Element scope=_getRootElement("component");
2296                //if(baseComponent.trim().length()>0)
2297                if(deepSearch!=null)
2298            scope.setAttribute("deep-search",Caster.toString(deepSearch.booleanValue()));
2299                
2300                else {
2301                    if(scope.hasAttribute("deep-search"))
2302                            scope.removeAttribute("deep-search");
2303                }
2304                    
2305            }
2306        
2307    
2308        public void updateComponentDefaultImport(String componentDefaultImport) throws SecurityException {
2309            checkWriteAccess();
2310            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2311            if(!hasAccess)
2312                throw new SecurityException("no access to update component setting");
2313            //config.resetBaseComponentPage();
2314            Element scope=_getRootElement("component");
2315            //if(baseComponent.trim().length()>0)
2316                    scope.setAttribute("component-default-import",componentDefaultImport);
2317        }
2318        
2319        
2320        
2321        
2322        /**
2323         * update the Component Data Member default access type
2324         * @param access
2325         * @throws SecurityException
2326         * @throws ExpressionException 
2327         */
2328        public void updateComponentDataMemberDefaultAccess(String strAccess) throws SecurityException, ExpressionException {
2329            checkWriteAccess(); 
2330            
2331            
2332            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2333            if(!hasAccess)
2334                throw new SecurityException("no access to update component setting");
2335            
2336            Element scope=_getRootElement("component");
2337    
2338            if(StringUtil.isEmpty(strAccess)){
2339                    scope.setAttribute("data-member-default-access","");
2340            }
2341            else{
2342                    scope.setAttribute("data-member-default-access",ComponentUtil.toStringAccess(ComponentUtil.toIntAccess(strAccess)));
2343            }
2344        } 
2345        
2346        /**
2347         * update the Component Data Member default access type
2348         * @param accessType
2349         * @throws SecurityException
2350         */
2351        public void updateTriggerDataMember(Boolean triggerDataMember) throws SecurityException {
2352            checkWriteAccess();
2353            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2354            if(!hasAccess)
2355                throw new SecurityException("no access to update trigger-data-member");
2356            
2357            Element scope=_getRootElement("component");
2358            scope.setAttribute("trigger-data-member",Caster.toString(triggerDataMember,""));
2359        }
2360    
2361            public void updateComponentUseShadow(Boolean useShadow) throws SecurityException {
2362            checkWriteAccess();
2363                    boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2364                    if(!hasAccess)
2365                throw new SecurityException("no access to update use-shadow");
2366            
2367            Element scope=_getRootElement("component");
2368            scope.setAttribute("use-shadow",Caster.toString(useShadow,""));
2369            }
2370    
2371            public void updateComponentLocalSearch(Boolean componentLocalSearch) throws SecurityException {
2372            checkWriteAccess();
2373                    boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2374                    if(!hasAccess)
2375                throw new SecurityException("no access to update component Local Search");
2376            
2377            Element scope=_getRootElement("component");
2378            scope.setAttribute("local-search",Caster.toString(componentLocalSearch,""));
2379            }
2380            
2381            public void updateComponentPathCache(Boolean componentPathCache) throws SecurityException {
2382                    checkWriteAccess();
2383                    boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2384                    if(!hasAccess)
2385                throw new SecurityException("no access to update component Cache Path");
2386            
2387            Element scope=_getRootElement("component");
2388            if(!Caster.toBooleanValue(componentPathCache,false))
2389                    config.clearComponentCache();
2390            scope.setAttribute("use-cache-path",Caster.toString(componentPathCache,""));
2391            }
2392            public void updateCTPathCache(Boolean ctPathCache) throws SecurityException {
2393                    checkWriteAccess();
2394                    if(!ConfigWebUtil.hasAccess(config, SecurityManager.TYPE_CUSTOM_TAG)) 
2395                            throw new SecurityException("no access to update custom tag setting");
2396                    
2397                     if(!Caster.toBooleanValue(ctPathCache,false))
2398                            config.clearCTCache();
2399                    Element scope=_getRootElement("custom-tag");
2400            scope.setAttribute("use-cache-path",Caster.toString(ctPathCache,""));
2401            }
2402    
2403            
2404            
2405            
2406        /**
2407         * updates if debugging or not
2408         * @param debug if value is null server setting is used
2409         * @throws SecurityException
2410         */
2411        public void updateDebug(Boolean debug, Boolean database, Boolean exception, Boolean tracing, Boolean timer, 
2412                    Boolean implicitAccess, Boolean queryUsage) throws SecurityException {
2413            checkWriteAccess();
2414            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_DEBUGGING);
2415            if(!hasAccess)
2416                throw new SecurityException("no access to change debugging settings");
2417            Element debugging=_getRootElement("debugging");
2418            
2419            if(debug!=null)debugging.setAttribute("debug",Caster.toString(debug.booleanValue()));
2420            else debugging.removeAttribute("debug");
2421            
2422            if(database!=null)debugging.setAttribute("database",Caster.toString(database.booleanValue()));
2423            else debugging.removeAttribute("database");
2424            
2425            if(exception!=null)debugging.setAttribute("exception",Caster.toString(exception.booleanValue()));
2426            else debugging.removeAttribute("exception");
2427            
2428            if(tracing!=null)debugging.setAttribute("tracing",Caster.toString(tracing.booleanValue()));
2429            else debugging.removeAttribute("tracing");
2430            
2431            if(timer!=null)debugging.setAttribute("timer",Caster.toString(timer.booleanValue()));
2432            else debugging.removeAttribute("timer");
2433    
2434            if(implicitAccess!=null)debugging.setAttribute("implicit-access",Caster.toString(implicitAccess.booleanValue()));
2435            else debugging.removeAttribute("implicit-access");
2436            
2437            if(queryUsage!=null)debugging.setAttribute("query-usage",Caster.toString(queryUsage.booleanValue()));
2438            else debugging.removeAttribute("query-usage");
2439            
2440            
2441        }
2442    
2443        /**
2444         * updates the DebugTemplate
2445         * @param template
2446         * @throws SecurityException
2447         */
2448        public void updateDebugTemplate(String template) throws SecurityException {
2449            checkWriteAccess();
2450            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_DEBUGGING);
2451            if(!hasAccess)
2452                throw new SecurityException("no access to change debugging settings");
2453    
2454            Element debugging=_getRootElement("debugging");
2455            //if(template.trim().length()>0)
2456                    debugging.setAttribute("template",template);
2457        }
2458        
2459        /**
2460         * updates the ErrorTemplate
2461         * @param template
2462         * @throws SecurityException
2463         */
2464        public void updateErrorTemplate(int statusCode,String template) throws SecurityException {
2465            checkWriteAccess();
2466            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_DEBUGGING);
2467            if(!hasAccess)
2468                throw new SecurityException("no access to change error settings");
2469    
2470            Element error=_getRootElement("error");
2471            //if(template.trim().length()>0)
2472                    error.setAttribute("template-"+statusCode,template);
2473        }
2474        
2475    
2476        public void updateErrorStatusCode(Boolean doStatusCode) throws SecurityException {
2477            checkWriteAccess();
2478            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_DEBUGGING);
2479            if(!hasAccess)
2480                throw new SecurityException("no access to change error settings");
2481    
2482            Element error=_getRootElement("error");
2483            error.setAttribute("status-code",Caster.toString(doStatusCode,""));
2484        }
2485    
2486        /**
2487         * updates the DebugTemplate
2488         * @param template
2489         * @throws SecurityException
2490         */
2491        public void updateComponentDumpTemplate(String template) throws SecurityException {
2492            checkWriteAccess();
2493            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2494            if(!hasAccess)
2495                throw new SecurityException("no access to update component setting");
2496            
2497            Element component=_getRootElement("component");
2498            //if(template.trim().length()>0)
2499                    component.setAttribute("dump-template",template);
2500        }
2501        
2502        /* *
2503         * updates the if memory usage will be logged or not
2504         * @param logMemoryUsage
2505         * @throws SecurityException
2506         * /
2507        public void updateLogMemoryUsage(boolean logMemoryUsage) throws SecurityException {
2508            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_DEBUGGING);
2509            if(!hasAccess)
2510                throw new SecurityException("no access to change debugging settings");
2511            
2512            Element debugging=_getRootElement("debugging");
2513            debugging.setAttribute("log-memory-usage",Caster.toString(logMemoryUsage));
2514        }*/
2515        
2516        /* *
2517         * updates the Memory Logger
2518         * @param memoryLogger
2519         * @throws SecurityException
2520         * /
2521        public void updateMemoryLogger(String memoryLogger) throws SecurityException {
2522            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_DEBUGGING);
2523            if(!hasAccess)
2524                throw new SecurityException("no access to change debugging settings");
2525            
2526            Element debugging=_getRootElement("debugging");
2527            if(memoryLogger.trim().length()>0)debugging.setAttribute("memory-log",memoryLogger);
2528        }*/
2529    
2530        private Element _getRootElement(String name) {
2531            Element el=ConfigWebFactory.getChildByName(doc.getDocumentElement(),name);
2532            if(el==null) {
2533                el=doc.createElement(name);
2534                doc.getDocumentElement().appendChild(el);
2535            }
2536            return el;
2537        }
2538    
2539        private Element _getRootElement(String name, boolean insertBefore,boolean doNotCreate) {
2540            return ConfigWebFactory.getChildByName(doc.getDocumentElement(),name,insertBefore,doNotCreate);
2541        }
2542        
2543        /**
2544         * @param setting
2545         * @param file
2546         * @param directJavaAccess
2547         * @param mail
2548         * @param datasource
2549         * @param mapping
2550         * @param customTag
2551         * @param cfxSetting
2552         * @param cfxUsage
2553         * @param debugging
2554         * @param search 
2555         * @param scheduledTasks 
2556         * @param tagExecute
2557         * @param tagImport
2558         * @param tagObject
2559         * @param tagRegistry
2560         * @throws SecurityException
2561         */
2562        public void updateDefaultSecurity(short setting, short file,Resource[] fileAccess,short directJavaAccess,
2563                   short mail, short datasource, short mapping, short remote, short customTag,
2564                  short cfxSetting, short cfxUsage, short debugging,
2565             short search, short scheduledTasks,
2566             short tagExecute,short tagImport, short tagObject, short tagRegistry,
2567             short cache, short gateway,short orm,
2568             short accessRead, short accessWrite) throws SecurityException {
2569            checkWriteAccess();
2570            if(!(config instanceof ConfigServer))
2571                throw new SecurityException("can't change security settings from this context");
2572            
2573            Element security=_getRootElement("security");
2574            updateSecurityFileAccess(security,fileAccess,file);
2575            security.setAttribute("setting",            SecurityManagerImpl.toStringAccessValue(setting));
2576            security.setAttribute("file",               SecurityManagerImpl.toStringAccessValue(file));
2577            security.setAttribute("direct_java_access", SecurityManagerImpl.toStringAccessValue(directJavaAccess));
2578            security.setAttribute("mail",               SecurityManagerImpl.toStringAccessValue(mail));
2579            security.setAttribute("datasource",         SecurityManagerImpl.toStringAccessValue(datasource));
2580            security.setAttribute("mapping",            SecurityManagerImpl.toStringAccessValue(mapping));
2581            security.setAttribute("remote",                 SecurityManagerImpl.toStringAccessValue(remote));
2582            security.setAttribute("custom_tag",         SecurityManagerImpl.toStringAccessValue(customTag));
2583            security.setAttribute("cfx_setting",        SecurityManagerImpl.toStringAccessValue(cfxSetting));
2584            security.setAttribute("cfx_usage",          SecurityManagerImpl.toStringAccessValue(cfxUsage));
2585            security.setAttribute("debugging",          SecurityManagerImpl.toStringAccessValue(debugging));
2586            security.setAttribute("search",             SecurityManagerImpl.toStringAccessValue(search));
2587            security.setAttribute("scheduled_task",     SecurityManagerImpl.toStringAccessValue(scheduledTasks));
2588    
2589            security.setAttribute("tag_execute",        SecurityManagerImpl.toStringAccessValue(tagExecute));
2590            security.setAttribute("tag_import",         SecurityManagerImpl.toStringAccessValue(tagImport));
2591            security.setAttribute("tag_object",         SecurityManagerImpl.toStringAccessValue(tagObject));
2592            security.setAttribute("tag_registry",         SecurityManagerImpl.toStringAccessValue(tagRegistry));
2593            security.setAttribute("cache",       SecurityManagerImpl.toStringAccessValue(cache));
2594            security.setAttribute("gateway",       SecurityManagerImpl.toStringAccessValue(gateway));
2595            security.setAttribute("orm",       SecurityManagerImpl.toStringAccessValue(orm));
2596    
2597            security.setAttribute("access_read",       SecurityManagerImpl.toStringAccessRWValue(accessRead));
2598            security.setAttribute("access_write",      SecurityManagerImpl.toStringAccessRWValue(accessWrite));
2599        
2600        
2601        
2602        }
2603        
2604        private void removeSecurityFileAccess(Element parent) {
2605            Element[] children = ConfigWebFactory.getChildren(parent,"file-access");
2606            
2607            // remove existing
2608            if(!ArrayUtil.isEmpty(children)){
2609                    for(int i=children.length-1;i>=0;i--){
2610                            parent.removeChild(children[i]);
2611                    }
2612            }
2613        }
2614        
2615        private void updateSecurityFileAccess(Element parent,Resource[] fileAccess, short file) {
2616            removeSecurityFileAccess(parent);
2617            
2618            // insert
2619            if(!ArrayUtil.isEmpty(fileAccess) && file!=SecurityManager.VALUE_ALL){
2620                    Element fa;
2621                    for(int i=0;i<fileAccess.length;i++){
2622                            fa=doc.createElement("file-access");
2623                            fa.setAttribute("path", fileAccess[i].getAbsolutePath());
2624                            parent.appendChild(fa);
2625                    }
2626            }
2627            
2628            }
2629    
2630    
2631            /**
2632         * update a security manager that match the given id
2633         * @param id
2634         * @param setting
2635         * @param file
2636         * @param file_access 
2637         * @param directJavaAccess
2638         * @param mail
2639         * @param datasource
2640         * @param mapping
2641         * @param customTag
2642         * @param cfxSetting
2643         * @param cfxUsage
2644         * @param debugging
2645         * @param search 
2646         * @param scheduledTasks 
2647         * @param tagExecute
2648         * @param tagImport
2649         * @param tagObject
2650         * @param tagRegistry
2651         * @throws SecurityException
2652         * @throws ApplicationException
2653         */
2654        public void updateSecurity(String id, short setting, short file,Resource[] fileAccess, short directJavaAccess,
2655               short mail, short datasource, short mapping, short remote, short customTag,
2656              short cfxSetting, short cfxUsage, short debugging,
2657              short search, short scheduledTasks,
2658              short tagExecute,short tagImport, short tagObject, short tagRegistry, 
2659              short cache,short gateway,short orm,
2660              short accessRead, short accessWrite) throws SecurityException, ApplicationException {
2661            checkWriteAccess();
2662            if(!(config instanceof ConfigServer))
2663                throw new SecurityException("can't change security settings from this context");
2664            
2665            Element security=_getRootElement("security");
2666            Element[] children = ConfigWebFactory.getChildren(security,"accessor");
2667            Element accessor=null;
2668            for(int i=0;i<children.length;i++) {
2669                if(id.equals(children[i].getAttribute("id"))) {
2670                    accessor=children[i];
2671                }
2672            }
2673            if(accessor==null) throw new ApplicationException("there is noc Security Manager for id ["+id+"]");
2674            updateSecurityFileAccess(accessor,fileAccess,file);
2675            
2676            accessor.setAttribute("setting",            SecurityManagerImpl.toStringAccessValue(setting));
2677            accessor.setAttribute("file",               SecurityManagerImpl.toStringAccessValue(file));
2678            accessor.setAttribute("direct_java_access", SecurityManagerImpl.toStringAccessValue(directJavaAccess));
2679            accessor.setAttribute("mail",               SecurityManagerImpl.toStringAccessValue(mail));
2680            accessor.setAttribute("datasource",         SecurityManagerImpl.toStringAccessValue(datasource));
2681            accessor.setAttribute("mapping",            SecurityManagerImpl.toStringAccessValue(mapping));
2682            accessor.setAttribute("remote",                 SecurityManagerImpl.toStringAccessValue(remote));
2683            accessor.setAttribute("custom_tag",         SecurityManagerImpl.toStringAccessValue(customTag));
2684            accessor.setAttribute("cfx_setting",        SecurityManagerImpl.toStringAccessValue(cfxSetting));
2685            accessor.setAttribute("cfx_usage",          SecurityManagerImpl.toStringAccessValue(cfxUsage));
2686            accessor.setAttribute("debugging",          SecurityManagerImpl.toStringAccessValue(debugging));
2687            accessor.setAttribute("search",             SecurityManagerImpl.toStringAccessValue(search));
2688            accessor.setAttribute("scheduled_task",     SecurityManagerImpl.toStringAccessValue(scheduledTasks));
2689            accessor.setAttribute("cache",     SecurityManagerImpl.toStringAccessValue(cache));
2690            accessor.setAttribute("gateway",     SecurityManagerImpl.toStringAccessValue(gateway));
2691            accessor.setAttribute("orm",     SecurityManagerImpl.toStringAccessValue(orm));
2692            
2693            accessor.setAttribute("tag_execute",        SecurityManagerImpl.toStringAccessValue(tagExecute));
2694            accessor.setAttribute("tag_import",         SecurityManagerImpl.toStringAccessValue(tagImport));
2695            accessor.setAttribute("tag_object",         SecurityManagerImpl.toStringAccessValue(tagObject));
2696            accessor.setAttribute("tag_registry",       SecurityManagerImpl.toStringAccessValue(tagRegistry));
2697    
2698            accessor.setAttribute("access_read",       SecurityManagerImpl.toStringAccessRWValue(accessRead));
2699            accessor.setAttribute("access_write",      SecurityManagerImpl.toStringAccessRWValue(accessWrite));
2700        }
2701        
2702        
2703        
2704        
2705        /**
2706         * @return returns the default password
2707         * @throws SecurityException
2708         */
2709        public String getDefaultPassword() throws SecurityException {
2710            checkReadAccess();
2711            if(config instanceof ConfigServerImpl) {
2712                return ((ConfigServerImpl)config).getDefaultPassword();
2713            }
2714            throw new SecurityException("can't access default password within this context");
2715        }
2716        /**
2717         * @param password
2718         * @throws SecurityException 
2719         */
2720        public void updateDefaultPassword(String password) throws SecurityException {
2721            checkWriteAccess();
2722            Element root=doc.getDocumentElement();
2723            root.setAttribute("default-password",new BlowfishEasy("tpwisgh").encryptString(password));
2724            ((ConfigServerImpl)config).setDefaultPassword(password);
2725        }
2726    
2727            public void removeDefaultPassword() throws SecurityException {
2728                    checkWriteAccess();
2729            Element root=doc.getDocumentElement();
2730            root.removeAttribute("default-password");
2731            ((ConfigServerImpl)config).setDefaultPassword(null);
2732            }
2733        
2734        /**
2735         * session type update
2736         * @param type
2737         * @throws SecurityException
2738         */
2739        public void updateSessionType(String type) throws SecurityException {
2740            checkWriteAccess();
2741            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2742            if(!hasAccess) throw new SecurityException("no access to update scope setting");
2743            
2744            type=type.toLowerCase().trim();
2745            
2746            Element scope=_getRootElement("scope");
2747            scope.setAttribute("session-type",type);
2748        }
2749        
2750        public void updateLocalMode(String mode) throws SecurityException {
2751            checkWriteAccess();
2752            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_SETTING);
2753            if(!hasAccess) throw new SecurityException("no access to update scope setting");
2754            
2755            mode=mode.toLowerCase().trim();
2756            Element scope=_getRootElement("scope");
2757            scope.setAttribute("local-mode",mode);
2758        }
2759        
2760    
2761    
2762    
2763            public void updateRestList(Boolean list) throws SecurityException {
2764                    checkWriteAccess();
2765            boolean hasAccess=true;// TODO ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_REST);
2766            if(!hasAccess) throw new SecurityException("no access to update rest setting");
2767            
2768            
2769            Element rest=_getRootElement("rest");
2770            if(list==null) {
2771                    if(rest.hasAttribute("list"))rest.removeAttribute("list");
2772            }
2773            else rest.setAttribute("list", Caster.toString(list.booleanValue()));
2774            }
2775            
2776            /*public void updateRestAllowChanges(Boolean allowChanges) throws SecurityException {
2777                    checkWriteAccess();
2778            boolean hasAccess=true;// TODO ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_REST);
2779            if(!hasAccess) throw new SecurityException("no access to update rest setting");
2780            
2781            
2782            Element rest=_getRootElement("rest");
2783            if(allowChanges==null) {
2784                    if(rest.hasAttribute("allow-changes"))rest.removeAttribute("allow-changes");
2785            }
2786            else rest.setAttribute("allow-changes", Caster.toString(allowChanges.booleanValue()));
2787            }*/
2788            
2789    
2790        /**
2791         * updates update settingd for railo
2792         * @param type
2793         * @param location
2794         * @throws SecurityException
2795         */
2796        public void updateUpdate(String type, String location) throws SecurityException {
2797            checkWriteAccess();
2798            
2799            if(!(config instanceof ConfigServer)) {
2800                throw new SecurityException("can't change update setting from this context, access is denied");
2801            }
2802            Element update=_getRootElement("update");
2803            update.setAttribute("type",type);
2804            try {
2805                            location=HTTPUtil.toURL(location).toString();
2806                    } 
2807            catch (Throwable e) {}
2808            update.setAttribute("location",location);
2809        }
2810        
2811        /**
2812         * creates a individual security manager based on the default security manager
2813         * @param id
2814         * @throws DOMException 
2815         * @throws PageException 
2816         */
2817        public void createSecurityManager(String password,String id) throws DOMException, PageException {
2818            checkWriteAccess();
2819            ConfigServerImpl cs=(ConfigServerImpl) config.getConfigServer(password);
2820            SecurityManagerImpl dsm = (SecurityManagerImpl) cs.getDefaultSecurityManager().cloneSecurityManager();
2821            cs.setSecurityManager(id,dsm);
2822            
2823            Element security=_getRootElement("security");
2824            Element accessor=null;
2825            
2826            Element[] children = ConfigWebFactory.getChildren(security,"accessor");
2827            for(int i=0;i<children.length;i++) {
2828                if(id.equals(children[i].getAttribute("id"))) {
2829                    accessor=children[i];             
2830                }
2831            }
2832            if(accessor==null) {
2833                accessor=doc.createElement("accessor");
2834                security.appendChild(accessor);
2835            }
2836            
2837            updateSecurityFileAccess(accessor,dsm.getCustomFileAccess(),dsm.getAccess(SecurityManager.TYPE_FILE));
2838            
2839            
2840            accessor.setAttribute("id",id);
2841            accessor.setAttribute("setting",            SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManager.TYPE_SETTING)));
2842            accessor.setAttribute("file",               SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManager.TYPE_FILE)));
2843            accessor.setAttribute("direct_java_access", SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManager.TYPE_DIRECT_JAVA_ACCESS)));
2844            accessor.setAttribute("mail",               SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManager.TYPE_MAIL)));
2845            accessor.setAttribute("datasource",         SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManager.TYPE_DATASOURCE)));
2846            accessor.setAttribute("mapping",            SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManager.TYPE_MAPPING)));
2847            accessor.setAttribute("custom_tag",         SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManager.TYPE_CUSTOM_TAG)));
2848            accessor.setAttribute("cfx_setting",        SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManager.TYPE_CFX_SETTING)));
2849            accessor.setAttribute("cfx_usage",          SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManager.TYPE_CFX_USAGE)));
2850            accessor.setAttribute("debugging",          SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManager.TYPE_DEBUGGING)));
2851            accessor.setAttribute("cache",                  SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManagerImpl.TYPE_CACHE)));
2852            accessor.setAttribute("gateway",                SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManagerImpl.TYPE_GATEWAY)));
2853            accessor.setAttribute("orm",                    SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManagerImpl.TYPE_ORM)));
2854    
2855            accessor.setAttribute("tag_execute",        SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManager.TYPE_TAG_EXECUTE)));
2856            accessor.setAttribute("tag_import",         SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManager.TYPE_TAG_IMPORT)));
2857            accessor.setAttribute("tag_object",         SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManager.TYPE_TAG_OBJECT)));
2858            accessor.setAttribute("tag_registry",       SecurityManagerImpl.toStringAccessValue(dsm.getAccess(SecurityManager.TYPE_TAG_REGISTRY)));
2859            
2860        }
2861    
2862    
2863        /**
2864         * remove security manager matching given id
2865         * @param id
2866         * @throws PageException 
2867         */
2868        public void removeSecurityManager(String password,String id) throws PageException {
2869            checkWriteAccess();
2870            ((ConfigServerImpl)config.getConfigServer(password)).removeSecurityManager(id);
2871            
2872            Element security=_getRootElement("security");
2873           
2874            
2875            Element[] children = ConfigWebFactory.getChildren(security,"accessor");
2876            for(int i=0;i<children.length;i++) {
2877                if(id.equals(children[i].getAttribute("id"))) {
2878                    security.removeChild(children[i]);
2879                }
2880            }
2881        }
2882    
2883        /**
2884         * run update from cfml engine
2885         * @throws PageException
2886         */
2887        public void runUpdate(String password) throws PageException {
2888            checkWriteAccess();
2889            ConfigServerImpl cs = (ConfigServerImpl) config.getConfigServer(password);
2890            CFMLEngineFactory factory = cs.getCFMLEngine().getCFMLEngineFactory();
2891            synchronized(factory){
2892                    try {
2893                        factory.update(cs.getPassword());
2894                    } 
2895                    catch (Exception e) {
2896                        throw Caster.toPageException(e);
2897                    }
2898            }
2899            
2900        }
2901        
2902        /**
2903         * run update from cfml engine
2904         * @throws PageException
2905         */
2906        public void removeLatestUpdate(String password) throws PageException {
2907            _removeUpdate(password,true);
2908        }
2909        
2910        public void removeUpdate(String password) throws PageException {
2911            _removeUpdate(password,false);
2912        }
2913        
2914        private void _removeUpdate(String password,boolean onlyLatest) throws PageException {
2915            checkWriteAccess();
2916            ConfigServerImpl cs = (ConfigServerImpl) config.getConfigServer(password);
2917            try {
2918                    CFMLEngineFactory factory = cs.getCFMLEngine().getCFMLEngineFactory();
2919                    
2920                    if(onlyLatest){
2921                            try{
2922                                    factory.removeLatestUpdate(cs.getPassword());
2923                            }
2924                            catch(Throwable t)      {
2925                                    removeLatestUpdateOld(factory,cs.getPassword());
2926                            }
2927                    }
2928                    else factory.removeUpdate(cs.getPassword());
2929                    
2930                    
2931            } 
2932            catch (Exception e) {
2933                throw Caster.toPageException(e);
2934            }
2935        }
2936        
2937            private String getCoreExtension() throws ServletException {
2938            URL res = new TP().getClass().getResource("/core/core.rcs");
2939            if(res!=null) return "rcs";
2940            
2941            res = new TP().getClass().getResource("/core/core.rc");
2942            if(res!=null) return "rc";
2943            
2944            throw new ServletException("missing core file");
2945            }
2946            
2947            private boolean isNewerThan(int left, int right) {
2948            return left>right;
2949        }
2950            
2951        private boolean removeLatestUpdateOld(CFMLEngineFactory factory, String password) throws IOException, ServletException {
2952            File patchDir = new File(factory.getResourceRoot(),"patches");
2953            if(!patchDir.exists())patchDir.mkdirs();
2954            
2955            File[] patches=patchDir.listFiles(new ExtensionFilter(new String[]{"."+getCoreExtension()}));
2956            File patch=null;
2957            for(int i=0;i<patches.length;i++) {
2958                     if(patch==null || isNewerThan(railo.loader.util.Util.toInVersion(patches[i].getName()),railo.loader.util.Util.toInVersion(patch.getName()))) {
2959                     patch=patches[i];
2960                 }
2961            }
2962            if(patch!=null && !patch.delete())patch.deleteOnExit();
2963            factory.restart(password);
2964            return true;
2965        }
2966        
2967        
2968        /*private Resource getPatchDirectory(CFMLEngine engine) throws IOException {
2969            //File f=engine.getCFMLEngineFactory().getResourceRoot();
2970            Resource res = ResourcesImpl.getFileResourceProvider().getResource(engine.getCFMLEngineFactory().getResourceRoot().getAbsolutePath());
2971            Resource pd = res.getRealResource("patches");
2972            if(!pd.exists())pd.mkdirs();
2973            return pd;
2974        }*/
2975        
2976        
2977        
2978        
2979        /**
2980         * run update from cfml engine
2981         * @throws PageException
2982         */
2983        public void restart(String password) throws PageException {
2984            checkWriteAccess();
2985            ConfigServerImpl cs = (ConfigServerImpl) config.getConfigServer(password);
2986            CFMLEngineFactory factory = cs.getCFMLEngine().getCFMLEngineFactory();
2987            synchronized(factory){
2988                    try {
2989                        factory.restart(cs.getPassword());
2990                    } 
2991                    catch (Exception e) {
2992                        throw Caster.toPageException(e);
2993                    }
2994            }
2995        }
2996    
2997            public void updateWebCharset(String charset) throws PageException {
2998            checkWriteAccess();
2999                    
3000            Element element = _getRootElement("charset");
3001                    if(StringUtil.isEmpty(charset)){
3002                            if(config instanceof ConfigWeb)
3003                                    element.removeAttribute("web-charset");
3004                            else
3005                                    element.setAttribute("web-charset", "UTF-8");
3006                    }
3007                    else {
3008                            charset=checkCharset(charset);
3009                            element.setAttribute("web-charset", charset);
3010                    }
3011            
3012                    element = _getRootElement("regional");
3013                    element.removeAttribute("default-encoding");// remove deprecated attribute
3014                    
3015            }
3016    
3017            public void updateResourceCharset(String charset) throws PageException {
3018            checkWriteAccess();
3019            
3020            Element element = _getRootElement("charset");
3021                    if(StringUtil.isEmpty(charset)){
3022                            element.removeAttribute("resource-charset");
3023                    }
3024                    else {
3025                            charset=checkCharset(charset);
3026                            element.setAttribute("resource-charset", charset);
3027                            
3028                    }
3029            
3030                    // update charset
3031                    
3032            }
3033    
3034            public void updateTemplateCharset(String charset) throws PageException {
3035            checkWriteAccess();
3036            
3037            Element element = _getRootElement("charset");
3038                    if(StringUtil.isEmpty(charset)){
3039                            element.removeAttribute("template-charset");
3040                    }
3041                    else {
3042                            charset=checkCharset(charset);
3043                            element.setAttribute("template-charset", charset);
3044                    }
3045            }
3046            
3047            private String checkCharset(String charset)  throws PageException{
3048                    charset=charset.trim();
3049                    if("system".equalsIgnoreCase(charset))
3050                            charset=SystemUtil.getCharset();
3051                    else if("jre".equalsIgnoreCase(charset))
3052                            charset=SystemUtil.getCharset();
3053                    else if("os".equalsIgnoreCase(charset))
3054                            charset=SystemUtil.getCharset();
3055                    
3056                    // check access
3057                    boolean hasAccess = ConfigWebUtil.hasAccess(config, SecurityManager.TYPE_SETTING);
3058                    if(!hasAccess) {
3059                            throw new SecurityException("no access to update regional setting");
3060                    }
3061                    
3062                    // check encoding
3063                    try {
3064                            IOUtil.checkEncoding(charset);
3065                    }
3066                    catch (IOException e) {throw Caster.toPageException(e);}
3067                    return charset;
3068            }
3069    
3070    
3071            private Resource getStoragDir(Config config) {
3072            Resource storageDir = config.getConfigDir().getRealResource("storage");
3073                    if(!storageDir.exists())storageDir.mkdirs();
3074                    return storageDir;
3075            }
3076            
3077            public void storageSet(Config config,String key, Object value) throws ConverterException, IOException, SecurityException {
3078            checkWriteAccess();
3079                    Resource storageDir = getStoragDir(config);
3080                    Resource storage=storageDir.getRealResource(key+".wddx");
3081                    
3082                    WDDXConverter converter =new WDDXConverter(config.getTimeZone(),true,true);
3083                    String wddx=converter.serialize(value);
3084                    IOUtil.write(storage, wddx, "UTF-8", false);
3085            }
3086    
3087    
3088            public Object storageGet(Config config, String key) throws ConverterException, IOException, SecurityException {
3089            checkReadAccess();
3090                    Resource storageDir = getStoragDir(config);
3091                    Resource storage=storageDir.getRealResource(key+".wddx");
3092                    if(!storage.exists()) throw new IOException("there is no storage with name "+key);
3093                    WDDXConverter converter =new WDDXConverter(config.getTimeZone(),true,true);
3094                    return converter.deserialize(IOUtil.toString(storage,"UTF-8"), true);
3095            }
3096    
3097    
3098            public void updateCustomTagDeepSearch(boolean customTagDeepSearch) throws SecurityException {
3099                    checkWriteAccess();
3100                    if(!ConfigWebUtil.hasAccess(config, SecurityManager.TYPE_CUSTOM_TAG)) 
3101                            throw new SecurityException("no access to update custom tag setting");
3102                    
3103                    Element element = _getRootElement("custom-tag");
3104                    element.setAttribute("custom-tag-deep-search",Caster.toString(customTagDeepSearch));
3105            }
3106    
3107            public void resetId() throws PageException {
3108                    checkWriteAccess();
3109                    Resource res=config.getConfigDir().getRealResource("id");
3110                    try {
3111                            if(res.exists())res.remove(false);
3112                    } catch (IOException e) {
3113                            throw Caster.toPageException(e);
3114                    }
3115            
3116            }
3117            
3118            public void updateCustomTagLocalSearch(boolean customTagLocalSearch) throws SecurityException {
3119                    checkWriteAccess();
3120                    if(!ConfigWebUtil.hasAccess(config, SecurityManager.TYPE_CUSTOM_TAG)) 
3121                            throw new SecurityException("no access to update custom tag setting");
3122                    
3123                    Element element = _getRootElement("custom-tag");
3124                    element.setAttribute("custom-tag-local-search",Caster.toString(customTagLocalSearch));
3125            }
3126            
3127    
3128    
3129            public void updateCustomTagExtensions(String extensions) throws PageException {
3130                    checkWriteAccess();
3131                    if(!ConfigWebUtil.hasAccess(config, SecurityManager.TYPE_CUSTOM_TAG)) 
3132                            throw new SecurityException("no access to update custom tag setting");
3133                    
3134                    // check
3135                    Array arr = ListUtil.listToArrayRemoveEmpty(extensions, ',');
3136                    ListUtil.trimItems(arr);
3137                    //throw new ApplicationException("you must define at least one extension");
3138                    
3139                    
3140                    // update charset
3141                    Element element = _getRootElement("custom-tag");
3142                    element.setAttribute("extensions",ListUtil.arrayToList(arr, ","));
3143            }
3144    
3145    
3146            public void updateRemoteClient(String label,String url, String type,
3147                            String securityKey, String usage, String adminPassword, String serverUsername, String serverPassword,
3148                            String proxyServer, String proxyUsername, String proxyPassword, String proxyPort) throws PageException {
3149                    checkWriteAccess();
3150                    
3151                    // SNSN
3152                    
3153                    boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManagerImpl.TYPE_REMOTE);
3154            if(!hasAccess)
3155                throw new SecurityException("no access to update remote client settings");
3156            
3157            
3158            Element clients=_getRootElement("remote-clients");
3159            
3160            if(StringUtil.isEmpty(url)) throw new ExpressionException("url can be a empty value");
3161            if(StringUtil.isEmpty(securityKey)) throw new ExpressionException("securityKey can be a empty value");
3162            if(StringUtil.isEmpty(adminPassword)) throw new ExpressionException("adminPassword can be a empty value");
3163            url=url.trim();
3164            securityKey=securityKey.trim();
3165            adminPassword=adminPassword.trim();
3166            
3167            Element[] children = ConfigWebFactory.getChildren(clients,"remote-client");
3168            
3169            // Update
3170            for(int i=0;i<children.length;i++) {
3171                Element el=children[i];
3172                String _url=el.getAttribute("url");
3173                            if(_url!=null && _url.equalsIgnoreCase(url)) {
3174                                    el.setAttribute("label",label);
3175                                    el.setAttribute("type",type);
3176                            el.setAttribute("usage",usage);
3177                            el.setAttribute("server-username",serverUsername);
3178                            el.setAttribute("proxy-server",proxyServer);
3179                            el.setAttribute("proxy-username",proxyUsername);
3180                            el.setAttribute("proxy-port",proxyPort);
3181                            el.setAttribute("security-key",ConfigWebFactory.encrypt(securityKey));
3182                            el.setAttribute("admin-password",ConfigWebFactory.encrypt(adminPassword));
3183                            el.setAttribute("server-password",ConfigWebFactory.encrypt(serverPassword));
3184                            el.setAttribute("proxy-password",ConfigWebFactory.encrypt(proxyPassword));
3185                            return ;
3186                            }
3187            }
3188            
3189            // Insert
3190            Element el = doc.createElement("remote-client");
3191    
3192            el.setAttribute("label",label);
3193                    el.setAttribute("url",url);
3194                    el.setAttribute("type",type);
3195                    el.setAttribute("usage",usage);
3196                    el.setAttribute("server-username",serverUsername);
3197                    el.setAttribute("proxy-server",proxyServer);
3198                    el.setAttribute("proxy-username",proxyUsername);
3199                    el.setAttribute("proxy-port",proxyPort);
3200                    el.setAttribute("security-key",ConfigWebFactory.encrypt(securityKey));
3201                    el.setAttribute("admin-password",ConfigWebFactory.encrypt(adminPassword));
3202                    el.setAttribute("server-password",ConfigWebFactory.encrypt(serverPassword));
3203                    el.setAttribute("proxy-password",ConfigWebFactory.encrypt(proxyPassword));
3204            
3205            
3206            clients.appendChild(el);
3207            }
3208    
3209            public void updateMonitor(String className,String type, String name, boolean logEnabled) throws PageException {
3210                    checkWriteAccess();
3211                    
3212            Element parent=_getRootElement("monitoring");
3213            
3214            
3215            Element[] children = ConfigWebFactory.getChildren(parent,"monitor");
3216            Element monitor=null;
3217            // Update
3218            for(int i=0;i<children.length;i++) {
3219                Element el=children[i];
3220                String _name=el.getAttribute("name");
3221                            if(_name!=null && _name.equalsIgnoreCase(name)) {
3222                                    monitor=el;
3223                                    break;
3224                            }
3225            }
3226            
3227            // Insert
3228            if(monitor==null) {
3229                    monitor = doc.createElement("monitor");
3230                    parent.appendChild(monitor);
3231            }
3232            
3233            monitor.setAttribute("class",className);
3234            monitor.setAttribute("type",type);
3235            monitor.setAttribute("name",name);
3236            monitor.setAttribute("log",Caster.toString(logEnabled));
3237            }
3238            
3239    
3240    
3241    
3242            public void updateExecutionLog(String className, Struct args, boolean enabled) {
3243                    Element el=_getRootElement("execution-log");
3244                    el.setAttribute("class",className);
3245                    el.setAttribute("arguments",toStringCSSStyle(args));
3246                    el.setAttribute("enabled",Caster.toString(enabled));
3247            }
3248            
3249            
3250            
3251            
3252            
3253    
3254            public void removeMonitor(String name) throws PageException {
3255                    checkWriteAccess();
3256                    
3257            Element parent=_getRootElement("monitoring");
3258            
3259            
3260            Element[] children = ConfigWebFactory.getChildren(parent,"monitor");
3261            // Update
3262            for(int i=0;i<children.length;i++) {
3263                Element el=children[i];
3264                String _name=el.getAttribute("name");
3265                            if(_name!=null && _name.equalsIgnoreCase(name)) {
3266                                    parent.removeChild(el);
3267                            }
3268            }
3269            
3270            }
3271    
3272    
3273            public void updateExtensionInfo(boolean enabled) {
3274                    Element extensions=_getRootElement("extensions");
3275                    extensions.setAttribute("enabled", Caster.toString(enabled));
3276            }
3277            
3278    
3279            public void updateExtensionProvider(String strUrl) {
3280                    Element extensions=_getRootElement("extensions");
3281                    Element[] children = ConfigWebFactory.getChildren(extensions,"provider");
3282            strUrl=strUrl.trim();
3283            
3284            // Update
3285                    Element el;
3286                    String url;
3287            for(int i=0;i<children.length;i++) {
3288                el=children[i];
3289                url=el.getAttribute("url");
3290                if( url!=null && url.trim().equalsIgnoreCase(strUrl)) {
3291                                    //el.setAttribute("cache-timeout",Caster.toString(cacheTimeout));
3292                                    return ;
3293                            }
3294            }
3295            
3296         // Insert
3297            el = doc.createElement("provider");
3298    
3299            el.setAttribute("url",strUrl);
3300            //el.setAttribute("cache-timeout",Caster.toString(cacheTimeout));
3301                    
3302                    XMLUtil.prependChild(extensions,el);
3303            }
3304            
3305    
3306            public void removeExtensionProvider(String strUrl) {
3307                    Element parent=_getRootElement("extensions");
3308                    Element[] children = ConfigWebFactory.getChildren(parent,"provider");
3309                    strUrl=strUrl.trim();
3310                    Element child;
3311                    String url;
3312            for(int i=0;i<children.length;i++) {
3313                child=children[i];
3314                url=child.getAttribute("url");
3315                            if(     url!=null && url.trim().equalsIgnoreCase(strUrl)) {
3316                                    parent.removeChild(child);
3317                                    return ;
3318                            }
3319            }
3320            }
3321            
3322    
3323            public void updateExtension(Extension extension) throws PageException {
3324                    checkWriteAccess();
3325                    
3326                    String uid = createUid(extension.getProvider(),extension.getId());
3327                    
3328                    Element extensions=_getRootElement("extensions");
3329                    Element[] children = ConfigWebFactory.getChildren(extensions,"extension");
3330            
3331            // Update
3332                    Element el;
3333                    String provider,id;
3334            for(int i=0;i<children.length;i++) {
3335                el=children[i];
3336                provider=el.getAttribute("provider");
3337                id=el.getAttribute("id");
3338                            if(uid.equalsIgnoreCase(createUid(provider, id))) {
3339                                    setExtensionAttrs(el,extension);
3340                                    return ;
3341                            }
3342            }
3343            
3344         // Insert
3345            el = doc.createElement("extension");
3346    
3347                    el.setAttribute("provider",extension.getProvider());
3348                    el.setAttribute("id",extension.getId());
3349                    setExtensionAttrs(el,extension);
3350            extensions.appendChild(el);
3351            }
3352    
3353    
3354            private String createUid(String provider, String id) throws PageException {
3355                    if(Decision.isUUId(id)) {
3356                            return Hash.invoke(config,id,null,null, 1);
3357                    }
3358                    return Hash.invoke(config,provider+id,null,null, 1);
3359            }
3360    
3361    
3362            private void setExtensionAttrs(Element el, Extension extension) {
3363            el.setAttribute("version",extension.getVersion());
3364            
3365            el.setAttribute("config",extension.getStrConfig());
3366            //el.setAttribute("config",new ScriptConverter().serialize(extension.getConfig()));
3367                    
3368                    el.setAttribute("category",extension.getCategory());
3369                    el.setAttribute("description",extension.getDescription());
3370                    el.setAttribute("image",extension.getImage());
3371                    el.setAttribute("label",extension.getLabel());
3372                    el.setAttribute("name",extension.getName());
3373    
3374                    el.setAttribute("author",extension.getAuthor());
3375                    el.setAttribute("type",extension.getType());
3376                    el.setAttribute("codename",extension.getCodename());
3377                    el.setAttribute("video",extension.getVideo());
3378                    el.setAttribute("support",extension.getSupport());
3379                    el.setAttribute("documentation",extension.getDocumentation());
3380                    el.setAttribute("forum",extension.getForum());
3381                    el.setAttribute("mailinglist",extension.getMailinglist());
3382                    el.setAttribute("network",extension.getNetwork());
3383                    el.setAttribute("created",Caster.toString(extension.getCreated(),null));
3384    
3385    
3386            }
3387            
3388    
3389            public void resetORMSetting() throws SecurityException {
3390                    boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManagerImpl.TYPE_ORM);
3391            
3392            if(!hasAccess)
3393                throw new SecurityException("no access to update ORM Settings");
3394            
3395                    
3396                    
3397                    Element orm=_getRootElement("orm");
3398                    orm.getParentNode().removeChild(orm);
3399            }
3400            
3401    
3402            public void updateORMSetting(ORMConfiguration oc) throws SecurityException {
3403                    boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManagerImpl.TYPE_ORM);
3404            
3405                    if(!hasAccess)
3406                throw new SecurityException("no access to update ORM Settings");
3407            
3408                    
3409                    
3410                    Element orm=_getRootElement("orm");
3411                    orm.setAttribute("autogenmap",Caster.toString(oc.autogenmap(),"true"));
3412                    orm.setAttribute("event-handler",Caster.toString(oc.eventHandler(),""));
3413                    orm.setAttribute("event-handling",Caster.toString(oc.eventHandling(),"false"));
3414                    orm.setAttribute("naming-strategy",Caster.toString(oc.namingStrategy(),""));
3415                    orm.setAttribute("flush-at-request-end",Caster.toString(oc.flushAtRequestEnd(),"true"));
3416                    orm.setAttribute("cache-provider",Caster.toString(oc.getCacheProvider(),""));
3417                    orm.setAttribute("cache-config",Caster.toString(oc.getCacheConfig(),"true"));
3418                    orm.setAttribute("catalog",Caster.toString(oc.getCatalog(),""));
3419                    orm.setAttribute("db-create",ORMConfigurationImpl.dbCreateAsString(oc.getDbCreate()));
3420                    orm.setAttribute("dialect",Caster.toString(oc.getDialect(),""));
3421                    orm.setAttribute("schema",Caster.toString(oc.getSchema(),""));
3422                    orm.setAttribute("log-sql",Caster.toString(oc.logSQL(),"false"));
3423                    orm.setAttribute("save-mapping",Caster.toString(oc.saveMapping(),"false"));
3424                    orm.setAttribute("secondary-cache-enable",Caster.toString(oc.secondaryCacheEnabled(),"false"));
3425                    orm.setAttribute("use-db-for-mapping",Caster.toString(oc.useDBForMapping(),"true"));
3426                    orm.setAttribute("orm-config",Caster.toString(oc.getOrmConfig(),""));
3427                    orm.setAttribute("sql-script",Caster.toString(oc.getSqlScript(),"true"));
3428                    
3429                    if(oc.isDefaultCfcLocation()) {
3430                            orm.removeAttribute("cfc-location");
3431                    }
3432                    else {
3433                            Resource[] locations = oc.getCfcLocations();
3434                            StringBuilder sb=new StringBuilder();
3435                            for(int i=0;i<locations.length;i++) {
3436                                    if(i!=0)sb.append(",");
3437                                    sb.append(locations[i].getAbsolutePath());
3438                            }
3439                            orm.setAttribute("cfc-location",sb.toString());
3440                    }
3441                    
3442                    
3443                    orm.setAttribute("sql-script",Caster.toString(oc.getSqlScript(),"true"));
3444                    
3445            }
3446    
3447    
3448            public void removeExtension(String provider, String id) throws SecurityException {
3449                    checkWriteAccess();
3450            
3451                    Element extensions=_getRootElement("extensions");
3452                    Element[] children = ConfigWebFactory.getChildren(extensions,"extension");
3453                    Element child;
3454                    String _provider, _id;
3455            for(int i=0;i<children.length;i++) {
3456                child=children[i];
3457                    _provider=child.getAttribute("provider");
3458                _id=child.getAttribute("id"); 
3459                    if(_provider!=null && _provider.equalsIgnoreCase(provider) && _id!=null && _id.equalsIgnoreCase(id)) {
3460                            extensions.removeChild(child);
3461                            }
3462                }
3463            }
3464            
3465            public void verifyExtensionProvider(String strUrl) throws PageException {
3466                    HTTPResponse method=null;
3467                    try {
3468                            URL url = HTTPUtil.toURL(strUrl+"?wsdl");
3469                            method = HTTPEngine.get(url, null, null, 2000,HTTPEngine.MAX_REDIRECT, null, null, null, null);
3470                    } 
3471                    catch (MalformedURLException e) {
3472                            throw new ApplicationException("url defintion ["+strUrl+"] is invalid");
3473                    } 
3474                    catch (IOException e) {
3475                            throw new ApplicationException("can't invoke ["+strUrl+"]",e.getMessage());
3476                    }
3477                    
3478                    if(method.getStatusCode()!=200){int code=method.getStatusCode();
3479            String text=method.getStatusText();
3480            String msg=code+" "+text;
3481            throw new HTTPException(msg,null,code,text,method.getURL());
3482                    }
3483                    //Object o = 
3484                            CreateObject.doWebService(null, strUrl+"?wsdl");
3485                            
3486            }
3487    
3488    
3489            public void updateTLD(Resource resTld) throws IOException {
3490                    updateLD(config.getTldFile(),resTld);
3491            }
3492            public void updateFLD(Resource resFld) throws IOException {
3493                    updateLD(config.getFldFile(),resFld);
3494            }
3495            
3496            private void updateLD(Resource dir,Resource res) throws IOException {
3497                    if(!dir.exists())dir.createDirectory(true);
3498            
3499            Resource file = dir.getRealResource(res.getName());
3500            if(file.length()!=res.length()){
3501                            ResourceUtil.copy(res, file);
3502                    }
3503            }
3504            
3505            static void updateTLD(Config config,InputStream is,String name, boolean closeStream) throws IOException {
3506                    updateLD(config.getTldFile(),is,name,closeStream);
3507            }
3508            static void updateFLD(Config config,InputStream is,String name, boolean closeStream) throws IOException {
3509                    updateLD(config.getFldFile(),is,name,closeStream);
3510            }
3511            
3512            private static void updateLD(Resource dir,InputStream is,String name, boolean closeStream) throws IOException {
3513                    if(!dir.exists())dir.createDirectory(true);
3514            Resource file = dir.getRealResource(name);
3515            IOUtil.copy(is, file.getOutputStream(), closeStream, true);
3516            }
3517    
3518            public void removeTLD(String name) throws IOException {
3519                    removeLD(config.getTldFile(),name);
3520            }
3521            
3522            public void removeTLDs(String[] names) throws IOException {
3523                    if(ArrayUtil.isEmpty(names)) return;
3524                    Resource file = config.getTldFile();
3525                    for(int i=0;i<names.length;i++){
3526                            removeLD(file,names[i]);
3527                    }
3528            }
3529    
3530            public void removeFLDs(String[] names) throws IOException {
3531                    if(ArrayUtil.isEmpty(names)) return;
3532                    Resource file = config.getFldFile();
3533                    for(int i=0;i<names.length;i++){
3534                            removeLD(file,names[i]);
3535                    }
3536            }
3537    
3538            public void removeFLD(String name) throws IOException {
3539                    removeLD(config.getFldFile(),name);
3540            }
3541            
3542            private void removeLD(Resource dir,String name) throws IOException {
3543                    if(dir.isDirectory()){
3544                            Resource[] children = dir.listResources(new MyResourceNameFilter(name));
3545                            for(int i=0;i<children.length;i++){
3546                                    children[i].remove(false);
3547                            }
3548                    }
3549            }
3550    
3551            public void updateJar(Resource resJar) throws IOException {
3552                    updateJar(config, resJar);
3553            }
3554            private static void updateJar(Config config, Resource resJar) throws IOException {
3555                    Resource lib = config.getConfigDir().getRealResource("lib");
3556                    if(!lib.exists())lib.mkdir();
3557            
3558                    Resource fileLib = lib.getRealResource(resJar.getName());
3559                    
3560                    if(fileLib.length()!=resJar.length()){
3561                            IOUtil.closeEL(config.getClassLoader());
3562                            ResourceUtil.copy(resJar, fileLib);
3563                            ConfigWebFactory.reloadLib((ConfigImpl) config);
3564                    }
3565            }
3566            
3567            static void updateJar(Config config, InputStream is, String name,boolean closeStream) throws IOException {
3568                    Resource lib = config.getConfigDir().getRealResource("lib");
3569                    if(!lib.exists())lib.mkdir();
3570            
3571                    Resource fileLib = lib.getRealResource(name);
3572                    
3573                    IOUtil.closeEL(config.getClassLoader());
3574                    IOUtil.copy(is, fileLib.getOutputStream(), closeStream, true);
3575                    ConfigWebFactory.reloadLib((ConfigImpl) config);
3576            }
3577    
3578            public void updateLogSettings(String name, int level,String virtualpath, int maxfile, int maxfilesize) throws ApplicationException {
3579                    name=name.toLowerCase().trim();
3580                    
3581                    
3582                    
3583                    
3584                    if("application".equals(name)) {
3585                            updateLogSettings(name, level,virtualpath, maxfile, maxfilesize, "application","application") ;
3586                    }
3587                    else if("exception".equals(name)) {
3588                            updateLogSettings(name, level,virtualpath, maxfile, maxfilesize, "application","exception") ;
3589                    }
3590                    else if("trace".equals(name)) {
3591                            updateLogSettings(name, level,virtualpath, maxfile, maxfilesize, "application","trace") ;
3592                    }
3593                    else if("thread".equals(name)) {
3594                            updateLogSettings(name, level,virtualpath, maxfile, maxfilesize, "application","thread") ;
3595                    }
3596                    else if("orm".equals(name)) {
3597                            updateLogSettings(name, level,virtualpath, maxfile, maxfilesize, "orm") ;
3598                    }
3599                    else if("gateway".equals(name)) {
3600                            updateLogSettings(name, level,virtualpath, maxfile, maxfilesize, "gateways") ;
3601                    }
3602                    else if("mail".equals(name)) {
3603                            updateLogSettings(name, level,virtualpath, maxfile, maxfilesize, "mail") ;
3604                    }  
3605                    else if("mapping".equals(name)) {
3606                            updateLogSettings(name, level,virtualpath, maxfile, maxfilesize, "mappings") ;
3607                    }  
3608                    else if("remote-client".equals(name)) {
3609                            updateLogSettings(name, level,virtualpath, maxfile, maxfilesize, "remote-clients") ;
3610                    }  
3611                    else if("request-timeout".equals(name)) {
3612                            updateLogSettings(name, level,virtualpath, maxfile, maxfilesize, "application","requesttimeout") ;
3613                    }  
3614                    else if("request-timeout".equals(name)) {
3615                            updateLogSettings(name, level,virtualpath, maxfile, maxfilesize, "application","requesttimeout") ;
3616                    }  
3617                    else if("schedule-task".equals(name)) {
3618                            if(config instanceof ConfigServer)
3619                                    throw new ApplicationException("scheduled task logger is not supported for server context");
3620                            updateLogSettings(name, level,virtualpath, maxfile, maxfilesize, "scheduler") ;
3621                    }  
3622                    else if("search".equals(name)) {
3623                            if(config instanceof ConfigServer)
3624                                    throw new ApplicationException("search logger is not supported for server context");
3625                            updateLogSettings(name, level,virtualpath, maxfile, maxfilesize, "search") ;
3626                    }  
3627                    else {
3628                            throw new ApplicationException("invalid logger name ["+name+"], supported names are [application,exception,trace,thread,orm,gateway,mail,mapping,remote-client,request-timeout,request-timeout,schedule-task,search]");
3629                    }
3630            }
3631    
3632            private void updateLogSettings(String name, int level, String virtualpath,int maxfile, int maxfilesize, String elName){
3633                    updateLogSettings(name, level, virtualpath,maxfile,maxfilesize,elName, null);
3634            }
3635    
3636            private void updateLogSettings(String name, int level, String virtualpath,int maxfile, int maxfilesize, String elName, String prefix) {
3637                    if(StringUtil.isEmpty(prefix)) prefix="";
3638                    else prefix+="-";
3639                    
3640                    Element el = _getRootElement(elName);
3641                    el.setAttribute(prefix+"log", virtualpath);
3642                    el.setAttribute(prefix+"log-level", LogUtil.toStringType(level, ""));
3643                    el.setAttribute(prefix+"log-max-file", Caster.toString(maxfile));
3644                    el.setAttribute(prefix+"log-max-file-size", Caster.toString(maxfilesize));
3645            }
3646    
3647    
3648            public void updateRemoteClientUsage(String code, String displayname) {
3649                    Struct usage = config.getRemoteClientUsage();
3650                    usage.setEL(code, displayname);
3651                    
3652                    Element extensions=_getRootElement("remote-clients");
3653                    extensions.setAttribute("usage", toStringURLStyle(usage));              
3654                    
3655            }
3656    
3657            public void updateClusterClass(String classname) throws PageException {
3658                    if(StringUtil.isEmpty(classname,true))
3659                            classname=ClusterNotSupported.class.getName();
3660                    
3661                    
3662            Class clazz=null;
3663                    try {
3664                            clazz = ClassUtil.loadClass(config.getClassLoader(),classname);
3665                    } catch (ClassException e) {
3666                            throw Caster.toPageException(e);
3667                    }
3668                    if(!Reflector.isInstaneOf(clazz,Cluster.class) && !Reflector.isInstaneOf(clazz,ClusterRemote.class))
3669                    throw new ApplicationException("class ["+clazz.getName()+"] does not implement interface ["+Cluster.class.getName()+"] or ["+ClusterRemote.class.getName()+"]");   
3670                    
3671    
3672                    Element scope=_getRootElement("scope");
3673                    scope.setAttribute("cluster-class", clazz.getName());   
3674                    ScopeContext.clearClusterScope();
3675            }
3676            
3677    
3678            
3679            public void updateVideoExecuterClass(String classname) throws PageException {
3680                    classname=classname.trim();
3681                    
3682                    if(StringUtil.isEmpty(classname,true))
3683                            classname=VideoExecuterNotSupported.class.getName();
3684                    
3685                    Class clazz=null;
3686                    try {
3687                            clazz = ClassUtil.loadClass(config.getClassLoader(),classname);
3688                    } catch (ClassException e) {
3689                            throw Caster.toPageException(e);
3690                    }
3691                    if(!Reflector.isInstaneOf(clazz,VideoExecuter.class))
3692                    throw new ApplicationException("class ["+clazz.getName()+"] does not implement interface ["+VideoExecuter.class.getName()+"]");   
3693                    
3694    
3695                    Element app=_getRootElement("video");
3696                    app.setAttribute("video-executer-class", clazz.getName());      
3697            }
3698            public void updateAdminSyncClass(String classname) throws PageException {
3699                    classname=classname.trim();
3700                    
3701                    if(StringUtil.isEmpty(classname,true))
3702                            classname=AdminSyncNotSupported.class.getName();
3703                    
3704                    Class clazz=null;
3705                    try {
3706                            clazz = ClassUtil.loadClass(config.getClassLoader(),classname);
3707                    } catch (ClassException e) {
3708                            throw Caster.toPageException(e);
3709                    }
3710                    if(!Reflector.isInstaneOf(clazz,AdminSync.class))
3711                    throw new ApplicationException("class ["+clazz.getName()+"] does not implement interface ["+AdminSync.class.getName()+"]");   
3712                    
3713    
3714                    Element app=_getRootElement("application");
3715                    app.setAttribute("admin-sync-class", clazz.getName());  
3716            }
3717            
3718            
3719            
3720            public void removeRemoteClientUsage(String code) {
3721                    Struct usage = config.getRemoteClientUsage();
3722                    usage.removeEL(KeyImpl.getInstance(code));
3723                    
3724                    Element extensions=_getRootElement("remote-clients");
3725                    extensions.setAttribute("usage", toStringURLStyle(usage));              
3726                    
3727            }
3728    
3729            public void removeJar(String strNames) throws IOException {
3730                    removeJar(ListUtil.listToStringArray(strNames, ','));
3731            }
3732            public void removeJar(String[] names) throws IOException {
3733                    if(ArrayUtil.isEmpty(names)) return;
3734                    
3735                    
3736                    Resource lib = config.getConfigDir().getRealResource("lib");
3737                    boolean changed=false;
3738                    if(lib.isDirectory()){
3739                            for(int n=0;n<names.length;n++){
3740                                    Resource[] children = lib.listResources(new MyResourceNameFilter(names[n].trim()));
3741                                    for(int i=0;i<children.length;i++){
3742                                            try {
3743                                                    changed=true;
3744                                                    IOUtil.closeEL(config.getClassLoader());
3745                                                    children[i].remove(false);
3746                                            } 
3747                                            catch (IOException ioe) {
3748                                                    if(children[i] instanceof File)
3749                                                            ((File)children[i]).deleteOnExit();
3750                                                    else{
3751                                                            ConfigWebFactory.reloadLib(this.config);
3752                                                            throw ioe;
3753                                                    }
3754                                            }
3755                                    }
3756                            }
3757                    }
3758                    if(changed){
3759                            ConfigWebFactory.reloadLib(this.config);
3760                            //new ResourceClassLoader(lib.listResources(),config.getClass().getClassLoader());
3761                    }
3762            }
3763    
3764            class MyResourceNameFilter implements ResourceNameFilter {
3765                    private String name;
3766                    public MyResourceNameFilter(String name){
3767                            this.name=name;
3768                    }
3769                    
3770                    @Override
3771                    public boolean accept(Resource parent, String name) {
3772                            return name.equals(this.name);
3773                    }
3774            }
3775    
3776             public void updateSerial(String serial) throws PageException {
3777                            
3778                    checkWriteAccess();
3779                    if(!(config instanceof ConfigServer)) {
3780                        throw new SecurityException("can't change serial number from this context, access is denied");
3781                    }
3782                    
3783                    Element root=doc.getDocumentElement();
3784                    if(!StringUtil.isEmpty(serial)){
3785                            serial=serial.trim();
3786                            if(!new SerialNumber(serial).isValid(serial))
3787                                    throw new SecurityException("serial number is invalid");
3788                            root.setAttribute("serial-number",serial);
3789                    }
3790                    else{
3791                            try{
3792                                    root.removeAttribute("serial-number");
3793                            }
3794                            catch(Throwable t){}
3795                    }
3796                    try{
3797                            root.removeAttribute("serial");
3798                    }
3799                    catch(Throwable t){}
3800                }
3801    
3802    
3803            public boolean updateLabel(String hash, String label) {
3804                    // check
3805            if(StringUtil.isEmpty(hash,true))  return false;
3806            if(StringUtil.isEmpty(label,true)) return false;
3807            
3808                    hash=hash.trim(); 
3809                    label=label.trim();
3810            
3811            Element labels=_getRootElement("labels");
3812            
3813            // Update
3814            Element[] children = ConfigWebFactory.getChildren(labels,"label");
3815            for(int i=0;i<children.length;i++) {
3816                String h=children[i].getAttribute("id");
3817                if(h!=null) {
3818                    if(h.equals(hash)) {
3819                                    Element el=children[i];
3820                                    if(label.equals(el.getAttribute("name"))) return false;
3821                                    el.setAttribute("name",label);
3822                                    return true;
3823                                    }
3824                }
3825            }
3826            
3827            // Insert
3828            Element el=doc.createElement("label");
3829            labels.appendChild(el);
3830            el.setAttribute("id",hash);
3831            el.setAttribute("name",label);
3832                    
3833            return true;
3834            }
3835            
3836            
3837            public void updateDebugSetting(int maxLogs) throws SecurityException {
3838                    checkWriteAccess();
3839            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_DEBUGGING);
3840            if(!hasAccess)
3841                throw new SecurityException("no access to change debugging settings");
3842                    
3843            
3844            Element debugging=_getRootElement("debugging");
3845            if(maxLogs==-1)
3846                    debugging.removeAttribute("max-records-logged");
3847            else
3848                    debugging.setAttribute("max-records-logged", Caster.toString(maxLogs));
3849            }
3850    
3851    
3852            public void updateDebugEntry(String type, String iprange,String label,String path,String fullname, Struct custom) throws SecurityException, IOException {
3853                    checkWriteAccess();
3854            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_DEBUGGING);
3855            if(!hasAccess)
3856                throw new SecurityException("no access to change debugging settings");
3857                    
3858            // leave this, this method throws a exception when ip range is not valid
3859            IPRange.getInstance(iprange);
3860            
3861                    String id=MD5.getDigestAsString(label.trim().toLowerCase());
3862                    type=type.trim();
3863                    iprange=iprange.trim();
3864                    label=label.trim();
3865                    
3866            Element debugging=_getRootElement("debugging");
3867            
3868            // Update
3869            Element[] children = ConfigWebFactory.getChildren(debugging,"debug-entry");
3870            Element el=null;
3871            for(int i=0;i<children.length;i++) {
3872                String _id=children[i].getAttribute("id");
3873                if(_id!=null) {
3874                    if(_id.equals(id)) {
3875                                    el=children[i];
3876                                    break;
3877                                    }
3878                }
3879            }
3880            
3881            // Insert
3882            if(el==null) {
3883                    el=doc.createElement("debug-entry");
3884                    debugging.appendChild(el);
3885                    el.setAttribute("id",id);
3886            }
3887            
3888    
3889                    el.setAttribute("type",type);
3890                    el.setAttribute("iprange",iprange);
3891                    el.setAttribute("label",label);
3892                    el.setAttribute("path",path);
3893                    el.setAttribute("fullname",fullname);
3894                    el.setAttribute("custom",toStringURLStyle(custom));
3895            }
3896    
3897    
3898    
3899    
3900            public void removeDebugEntry(String id) throws SecurityException {
3901                    checkWriteAccess();
3902            boolean hasAccess=ConfigWebUtil.hasAccess(config,SecurityManager.TYPE_DEBUGGING);
3903            if(!hasAccess)
3904                throw new SecurityException("no access to change debugging settings");
3905    
3906            
3907            Element debugging=_getRootElement("debugging");
3908            Element[] children = ConfigWebFactory.getChildren(debugging,"debug-entry");
3909            String _id;
3910            if(children.length>0) {
3911                    for(int i=0;i<children.length;i++) {
3912                        Element el=children[i];
3913                        _id=el.getAttribute("id");
3914                                    if(_id!=null && _id.equalsIgnoreCase(id)) {
3915                                    debugging.removeChild(children[i]);
3916                                    }
3917                    }
3918            }
3919            }
3920    
3921    
3922            public void updateLoginSettings(boolean captcha, int delay) {
3923    
3924            Element login=_getRootElement("login");
3925            login.setAttribute("captcha",Caster.toString(captcha));
3926            login.setAttribute("delay",Caster.toString(delay));
3927                    
3928            }
3929    
3930    
3931            public void updateCompilerSettings(Boolean dotNotationUpperCase, Boolean supressWSBeforeArg, Boolean nullSupport) throws PageException {
3932                    
3933                    Element element = _getRootElement("compiler");
3934                    
3935            checkWriteAccess();
3936            if(dotNotationUpperCase==null){
3937                            if(element.hasAttribute("dot-notation-upper-case"))
3938                                    element.removeAttribute("dot-notation-upper-case");
3939                    }
3940            else {
3941                    element.setAttribute("dot-notation-upper-case", Caster.toString(dotNotationUpperCase));
3942            }
3943            
3944            if(supressWSBeforeArg==null){
3945                            if(element.hasAttribute("supress-ws-before-arg"))
3946                                    element.removeAttribute("supress-ws-before-arg");
3947                    }
3948            else {
3949                    element.setAttribute("supress-ws-before-arg", Caster.toString(supressWSBeforeArg));
3950            }
3951            
3952            // full null support
3953            if(nullSupport==null){
3954                            if(element.hasAttribute("full-null-support"))
3955                                    element.removeAttribute("full-null-support");
3956                    }
3957            else {
3958                    element.setAttribute("full-null-support", Caster.toString(nullSupport));
3959            }
3960            
3961            
3962            
3963            }
3964            
3965            /*private void updatePlugin(Resource src) throws PageException, IOException {
3966            Resource srcDir = ResourceUtil.toResourceExisting(config, "zip://"+src.getAbsolutePath());
3967            if(!doAccept(srcDir))
3968                    throw new ApplicationException("plugin ["+src+"] is invalid, missing one of the following files [Action.cfc,language.xml] in root, existing files are ["+railo.runtime.type.util.ListUtil.arrayToList(srcDir.list(), ", ")+"]");
3969            
3970            String name=ResourceUtil.getName(src.getName());
3971            
3972            Resource dir = config.getConfigDir().getRealResource("context/admin/plugin");
3973            Resource trgDir = dir.getRealResource(name);
3974            if(trgDir.exists()){
3975                    trgDir.remove(true);
3976            }
3977            
3978            ResourceUtil.copyRecursive(srcDir, trgDir);    
3979            store();
3980        }
3981            public static boolean doAccept(Resource res) {
3982                    return res.isDirectory() && res.getRealResource("/Action.cfc").isFile() && res.getRealResource("/language.xml").isFile();
3983        }*/
3984    
3985            
3986            static Resource[] updateContext(ConfigImpl config,InputStream is,String realpath, boolean closeStream) throws PageException, IOException, SAXException {
3987            //ConfigWebAdmin admin = new ConfigWebAdmin(config, null);
3988            List<Resource> filesDeployed=new ArrayList<Resource>();
3989            ConfigWebAdmin._updateContext(config, is, realpath, closeStream, filesDeployed);
3990            return filesDeployed.toArray(new Resource[filesDeployed.size()]);
3991        }
3992    
3993            private static void _updateContext(Config config,InputStream is,String realpath, boolean closeStream,List<Resource> filesDeployed) throws PageException, IOException, SAXException {
3994            if(config instanceof ConfigServer) {
3995                    ConfigWeb[] webs = ((ConfigServer)config).getConfigWebs();
3996                    if(webs.length==0) return;
3997                    if(webs.length==1) {
3998                            _updateContext(webs[0], is,realpath,closeStream,filesDeployed);
3999                            return;
4000                    }
4001                    try{
4002                            byte[] barr = IOUtil.toBytes(is);
4003                            for(int i=0;i<webs.length;i++){
4004                                    _updateContext(webs[i], new ByteArrayInputStream(barr),realpath,true,filesDeployed);
4005                            }
4006                    }
4007                    finally {
4008                            if(closeStream)IOUtil.closeEL(is);
4009                    }
4010                    return ;
4011            }
4012                    
4013            // ConfigWeb
4014            Resource trg = config.getConfigDir().getRealResource("context").getRealResource(realpath);
4015            if(trg.exists()) trg.remove(true);
4016            Resource p = trg.getParentResource();
4017            if(!p.isDirectory()) p.createDirectory(true); 
4018            IOUtil.copy(is, trg.getOutputStream(false), closeStream,true);
4019            filesDeployed.add(trg);
4020            _store((ConfigImpl)config);
4021        }
4022            private boolean removeContexts(Config config,String[] realpathes, boolean store) throws PageException, IOException, SAXException {
4023                    if(ArrayUtil.isEmpty(realpathes)) return false;
4024                    boolean force=false;
4025                    for(int i=0;i<realpathes.length;i++){
4026                            if(removeContext(config, realpathes[i],store))
4027                                    force=true;
4028                    }
4029                    return force;
4030            }
4031            public boolean removeContext(Config config,String realpath, boolean _store) throws PageException, IOException, SAXException {
4032            
4033                    if(config instanceof ConfigServer) {
4034                    boolean store=false;
4035                            ConfigWeb[] webs = ((ConfigServer)config).getConfigWebs();
4036                    for(int i=0;i<webs.length;i++){
4037                            if(removeContext(webs[i], realpath,_store)) {
4038                                    store=true;
4039                            }
4040                    }
4041                    return store;
4042            }
4043                    
4044            // ConfigWeb
4045            Resource trg = config.getConfigDir().getRealResource("context").getRealResource(realpath);
4046            if(trg.exists()) {
4047                    trg.remove(true);
4048                    if(_store) ConfigWebAdmin._store((ConfigImpl) config);
4049                    return true;
4050            }
4051            return false;
4052        }
4053    
4054            static Resource[] updateApplication(ConfigImpl config,InputStream is,String realpath, boolean closeStream) throws PageException, IOException, SAXException {
4055            ConfigWebAdmin admin = new ConfigWebAdmin(config, null);
4056            List<Resource> filesDeployed=new ArrayList<Resource>();
4057            admin._updateApplication(config, is, realpath, closeStream, filesDeployed);
4058            return filesDeployed.toArray(new Resource[filesDeployed.size()]);
4059        }
4060    
4061            private void _updateApplication(Config config,InputStream is,String realpath, boolean closeStream,List<Resource> filesDeployed) throws PageException, IOException, SAXException {
4062            if(config instanceof ConfigServer) {
4063                    ConfigWeb[] webs = ((ConfigServer)config).getConfigWebs();
4064                    if(webs.length==0) return;
4065                    if(webs.length==1) {
4066                            _updateApplication(webs[0], is,realpath,closeStream,filesDeployed);
4067                            return;
4068                    }
4069                    try{
4070                            byte[] barr = IOUtil.toBytes(is);
4071                            for(int i=0;i<webs.length;i++){
4072                                    _updateApplication(webs[i], new ByteArrayInputStream(barr),realpath,true,filesDeployed);
4073                            }
4074                    }
4075                    finally {
4076                            if(closeStream)IOUtil.closeEL(is);
4077                    }
4078                    return ;
4079            }
4080                    
4081            // ConfigWeb
4082            
4083            
4084            Resource trg = config.getRootDirectory().getRealResource(realpath);
4085            if(trg.exists()) trg.remove(true);
4086            Resource p = trg.getParentResource();
4087            if(!p.isDirectory()) p.createDirectory(true); 
4088            IOUtil.copy(is, trg.getOutputStream(false), closeStream,true);
4089            filesDeployed.add(trg);
4090            //_store((ConfigImpl)config);
4091        }
4092    
4093            private void removeApplications(Config config,String[] realpathes) throws PageException, IOException, SAXException {
4094                    if(ArrayUtil.isEmpty(realpathes)) return;
4095                    for(int i=0;i<realpathes.length;i++){
4096                            removeApplication(config, realpathes[i]);
4097                    }
4098            }
4099            
4100            private void removeApplication(Config config,String realpath) throws PageException, IOException, SAXException {
4101            if(config instanceof ConfigServer) {
4102                    ConfigWeb[] webs = ((ConfigServer)config).getConfigWebs();
4103                            for(int i=0;i<webs.length;i++){
4104                                    removeApplication(webs[i], realpath);
4105                    }
4106                    
4107                    return ;
4108            }
4109                    
4110            // ConfigWeb
4111            Resource trg = config.getRootDirectory().getRealResource(realpath);
4112            if(trg.exists()) trg.remove(true);
4113        }
4114            
4115            public static void removeRHExtension(ConfigImpl config,String extensionID) throws SAXException, IOException, PageException {
4116                    ConfigWebAdmin admin = new ConfigWebAdmin(config, null);
4117                    boolean storeChildren = admin._removeExtension(config, extensionID);
4118                    admin._store();
4119                    
4120                    if(storeChildren && config instanceof ConfigServer) {
4121                            ConfigServer cs = (ConfigServer)config;
4122                            ConfigWeb[] webs = cs.getConfigWebs();
4123                            for(int i=0;i<webs.length;i++) {
4124                                    admin._store((ConfigImpl)webs[i]);
4125                            }
4126                    }
4127            }
4128    
4129            public boolean _removeExtension(ConfigImpl config,String extensionID) throws IOException, PageException, SAXException {
4130                    if(!Decision.isUUId(extensionID)) throw new IOException("id ["+extensionID+"] is invalid, it has to be a UUID"); 
4131                    
4132                    Element extensions=_getRootElement("extensions");
4133                    Element[] children = ConfigWebFactory.getChildren(extensions,"rhextension");// RailoHandledExtensions
4134            
4135            // Update
4136                    Element el;
4137                    String id;
4138                    String[] arr;
4139                    boolean storeChildren=false;
4140            for(int i=0;i<children.length;i++) {
4141                el=children[i];
4142                id=el.getAttribute("id");
4143                            if(extensionID.equalsIgnoreCase(id)) {
4144                                    
4145                                    // jars
4146                                    arr=_removeExtensionCheckOtherUsage(children,el,"jars");
4147                                    removeJar(arr);
4148                                    // flds
4149                                    arr=_removeExtensionCheckOtherUsage(children,el,"flds");
4150                                    removeFLDs(arr);
4151                                    // tlds
4152                                    arr=_removeExtensionCheckOtherUsage(children,el,"tlds");
4153                                    removeTLDs(arr);
4154                                    // contexts
4155                                    arr=_removeExtensionCheckOtherUsage(children,el,"contexts");
4156                                    storeChildren=removeContexts(config, arr,false);
4157                                    // applications
4158                                    arr=_removeExtensionCheckOtherUsage(children,el,"applications");
4159                                    removeApplications(config, arr);
4160                                    
4161                                    
4162                                    
4163                                    extensions.removeChild(el);
4164                                    return storeChildren;
4165                            }
4166            }
4167                    return false;
4168            }
4169            
4170            private String[] _removeExtensionCheckOtherUsage(Element[] children, Element curr,String type) {
4171                    String currVal=curr.getAttribute(type);
4172                    if(StringUtil.isEmpty(currVal)) return null;
4173                    
4174                    String otherVal;
4175                    Element other;
4176                    Set<String> currSet = ListUtil.toSet(ListUtil.trimItems(ListUtil.listToStringArray(currVal, ',')));
4177                    String[] otherArr;
4178                    for(int i=0;i<children.length;i++) {
4179                            other=children[i];
4180                            if(other==curr) continue;
4181                            otherVal=other.getAttribute(type);
4182                            if(StringUtil.isEmpty(otherVal)) continue;
4183                            otherArr=ListUtil.trimItems(ListUtil.listToStringArray(otherVal, ','));
4184                            for(int y=0;y<otherArr.length;y++) {
4185                                    currSet.remove(otherArr[y]);
4186                            }
4187                    }
4188                    return currSet.toArray(new String[currSet.size()]);
4189            }
4190    
4191    
4192            public static void updateRHExtension(ConfigImpl config,RHExtension rhExtension) throws SAXException, IOException, PageException {
4193                    ConfigWebAdmin admin = new ConfigWebAdmin(config, null);
4194                    admin._updateExtension(config, rhExtension);
4195                    admin._store();
4196            }
4197    
4198    
4199            public void _updateExtension(ConfigImpl config,RHExtension ext) throws IOException {
4200                    if(!Decision.isUUId(ext.getId())) throw new IOException("id ["+ext.getId()+"] is invalid, it has to be a UUID"); 
4201                    
4202                    Element extensions=_getRootElement("extensions");
4203                    Element[] children = ConfigWebFactory.getChildren(extensions,"rhextension");// RailoHandledExtensions
4204            
4205            // Update
4206                    Element el;
4207                    String provider,id;
4208            for(int i=0;i<children.length;i++) {
4209                el=children[i];
4210                provider=el.getAttribute("provider");
4211                id=el.getAttribute("id");
4212                            if(ext.getId().equalsIgnoreCase(id)) {
4213                                    setExtensionAttrs(el,ext);
4214                                    return ;
4215                            }
4216            }
4217            
4218         // Insert
4219            el = doc.createElement("rhextension");
4220            setExtensionAttrs(el,ext);
4221                    extensions.appendChild(el);
4222            
4223            }
4224    
4225    
4226            private void setExtensionAttrs(Element el, RHExtension ext) {
4227                    setAttr(el,"id", ext.getId());
4228                    setAttr(el,"name", ext.getName());
4229                    setAttr(el,"version", ext.getVersion());
4230                    setAttr(el,"jars",ListUtil.arrayToList(ext.getJars(), ","));
4231                    setAttr(el,"flds",ListUtil.arrayToList(ext.getFlds(), ","));
4232                    setAttr(el,"tlds",ListUtil.arrayToList(ext.getTlds(), ","));
4233                    setAttr(el,"contexts",ListUtil.arrayToList(ext.getContexts(), ","));
4234                    setAttr(el,"applications",ListUtil.arrayToList(ext.getApplications(), ","));    
4235            }
4236    
4237    
4238            private void setAttr(Element el, String name, String value) {
4239                    if(value==null) value="";
4240                    el.setAttribute(name, value);
4241            }
4242    }