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