001    package railo.runtime.tag;
002    
003    import java.io.IOException;
004    
005    import railo.commons.io.log.LogConsole;
006    import railo.commons.io.log.LogResource;
007    import railo.commons.io.res.Resource;
008    import railo.commons.lang.StringUtil;
009    import railo.runtime.config.Config;
010    import railo.runtime.exp.ApplicationException;
011    import railo.runtime.exp.PageException;
012    import railo.runtime.ext.tag.TagImpl;
013    import railo.runtime.op.Caster;
014    import railo.runtime.tag.util.DeprecatedUtil;
015    
016    /**
017    * Writes a message to a log file.
018    *
019    *
020    *
021    **/
022    public final class Log extends TagImpl {
023    
024        private final static short LOG_APPLICATION=10;
025        private final static short LOG_SCHEDULER=11;
026        private final static short LOG_CONSOLE=12;
027        
028        
029    
030            /** If you omit the file attribute, specifies the standard log file in which to write the message. 
031            **              Ignored if you specify a file attribute */
032            private short log=LOG_APPLICATION;
033    
034            /** The message text to log. */
035            private String text;
036    
037            /** The type or severity of the message. */
038            private short type=railo.commons.io.log.Log.LEVEL_INFO;
039            /**  */
040            private String file;
041    
042            /** Specifies whether to log the application name if one has been specified in a cfapplication tag. */
043            private boolean application;
044            private String charset=null;
045            
046            /**
047            * @see javax.servlet.jsp.tagext.Tag#release()
048            */
049            public void release()   {
050                    super.release();
051                    log=LOG_APPLICATION;
052                    type=railo.commons.io.log.Log.LEVEL_INFO;
053                    file=null;
054                    application=false;
055                    charset=null;
056            }
057    
058            /** set the value log
059            *  If you omit the file attribute, specifies the standard log file in which to write the message. 
060            *               Ignored if you specify a file attribute
061            * @param log value to set
062             * @throws ApplicationException
063            **/
064            public void setLog(String log) throws ApplicationException      {
065                    if(StringUtil.isEmpty(log,true)) return;
066                log=log.toLowerCase().trim();
067                if(log.equals("application")) this.log=LOG_APPLICATION;
068                else if(log.equals("scheduler")) this.log=LOG_SCHEDULER;
069                else if(log.equals("console")) this.log=LOG_CONSOLE;
070                    else 
071                        throw new ApplicationException("invalid value for attribute log ["+log+"]","valid values are [application, scheduler,console]");
072            }
073    
074            /** set the value text
075            *  The message text to log.
076            * @param text value to set
077            **/
078            public void setText(String text)        {
079                    this.text=text;
080            }
081    
082            /** set the value type
083            *  The type or severity of the message.
084            * @param type value to set
085             * @throws ApplicationException
086            **/
087            public void setType(String type) throws ApplicationException    {
088                type=type.toLowerCase().trim(); 
089                if(type.equals("information")) this.type=railo.commons.io.log.Log.LEVEL_INFO;
090                else if(type.equals("info")) this.type=railo.commons.io.log.Log.LEVEL_INFO;
091                else if(type.equals("warning")) this.type=railo.commons.io.log.Log.LEVEL_WARN;
092                else if(type.equals("warn")) this.type=railo.commons.io.log.Log.LEVEL_WARN;
093                else if(type.equals("error")) this.type=railo.commons.io.log.Log.LEVEL_ERROR;
094            else if(type.startsWith("fatal")) this.type=railo.commons.io.log.Log.LEVEL_FATAL;
095            else if(type.startsWith("debug")) this.type=railo.commons.io.log.Log.LEVEL_DEBUG;
096                    else
097                        throw new ApplicationException("invalid value for attribute type ["+type+"]",
098                          "valid values are [information,warning,error,fatal,debug]");
099    
100            }
101    
102            /** set the value time
103            *  Specifies whether to log the system time.
104            * @param time value to set
105             * @throws ApplicationException
106            **/
107            public void setTime(boolean useTime) throws ApplicationException        {
108                    if(useTime) return;
109                    DeprecatedUtil.tagAttribute(pageContext,"Log", "time");
110                throw new ApplicationException("attribute [time] for tag [log] is deprecated, only the value true is allowed");
111            }
112    
113            /** set the value file
114            *  
115            * @param file value to set
116             * @throws ApplicationException
117            **/
118            public void setFile(String file) throws ApplicationException    {
119                    if(StringUtil.isEmpty(file))return;
120                    
121                if(file.indexOf('/')!=-1 || file.indexOf('\\')!=-1)
122                    throw new ApplicationException("value ["+file+"] from attribute [file] at tag [log] can only contain a filename, file separators like [\\/] are not allowed");
123                    if(!file.endsWith(".log"))file+=".log";
124                    this.file=file;
125            }
126    
127            /** set the value date
128            *  Specifies whether to log the system date.
129            * @param date value to set
130             * @throws ApplicationException
131            **/
132            public void setDate(boolean useDate) throws ApplicationException        {
133                    if(useDate) return;
134                    DeprecatedUtil.tagAttribute(pageContext,"Log", "date");
135                throw new ApplicationException("attribute [date] for tag [log] is deprecated, only the value true is allowed");
136            }
137    
138            /** set the value thread
139            *  Specifies whether to log the thread ID. The thread ID identifies which internal service thread logged a 
140            *               message. Since a service thread normally services a CFML page request to completion, then moves on to 
141            *               the next queued request, the thread ID serves as a rough indication of which request logged a message. 
142            *               Leaving thread IDs turned on can help diagnose patterns of server activity.
143            * @param thread value to set
144             * @throws ApplicationException
145            **/
146            public void setThread(boolean thread) throws ApplicationException       {
147                    if(thread) return;
148                    DeprecatedUtil.tagAttribute(pageContext,"Log", "thread");
149                throw new ApplicationException("attribute [thread] for tag [log] is deprecated, only the value true is allowed");
150            }
151    
152            /** set the value application
153            *  Specifies whether to log the application name if one has been specified in a cfapplication tag.
154            * @param application value to set
155            **/
156            public void setApplication(boolean application) {
157                    this.application=application;
158            }
159    
160    
161            /**
162            * @throws PageException 
163             * @see javax.servlet.jsp.tagext.Tag#doStartTag()
164            */
165            public int doStartTag() throws PageException    {
166                railo.commons.io.log.Log logger;
167                Config config =pageContext.getConfig();
168                if(file==null) {
169                    if(log==LOG_SCHEDULER)logger=config.getScheduleLogger();
170                    else if(log==LOG_CONSOLE)logger=LogConsole.getInstance(config, railo.commons.io.log.Log.LEVEL_INFO);
171                    else logger=config.getApplicationLogger();
172                    
173                }
174                else {
175                    if(charset==null) charset=pageContext.getConfig().getResourceCharset();
176                    Resource logDir=config.getConfigDir().getRealResource("logs");
177                    if(!logDir.exists())logDir.mkdirs();
178                    try {
179                            Resource f = logDir.getRealResource(file);
180                    logger=new LogResource(f,railo.commons.io.log.Log.LEVEL_INFO,charset);
181                } catch (IOException e) {
182                    throw Caster.toPageException(e);
183                }
184                }
185                
186                
187                String contextName = pageContext.getApplicationContext().getName();
188                if(contextName==null || !application)contextName="";
189                logger.log(type,contextName,text);
190            //logger.write(toStringType(type),contextName,text);
191                    return SKIP_BODY;
192            }
193    
194            /**
195             * @param charset the charset to set
196             */
197            public void setCharset(String charset) {
198                    if(StringUtil.isEmpty(log,true)) return;
199                this.charset = charset;
200            }
201    }