001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019package lucee.runtime.exp;
020
021import java.util.ArrayList;
022import java.util.List;
023
024import lucee.commons.io.res.util.ResourceUtil;
025import lucee.runtime.PageContext;
026import lucee.runtime.config.Config;
027import lucee.runtime.err.ErrorPage;
028import lucee.runtime.type.Struct;
029import lucee.runtime.type.util.KeyConstants;
030
031
032/**
033 * Exception throwed by CFML Code
034 */
035public final class CustomTypeException extends PageExceptionImpl {
036        
037        private static final long serialVersionUID = 949287085391895177L;
038        
039        private int entryLevel;
040        
041        /**
042         * constructor of the Exception 
043         * @param message Exception Message
044         * @param detail Detailed Exception Message
045         * @param errorCode Error Code
046         * @param customType Type of the Exception
047         * @param entryLevel 
048         */
049        public CustomTypeException(String message, String detail, String errorCode, String customType,String extendedinfo) {
050                this(message, detail, errorCode, customType, extendedinfo, 1);
051        }
052        
053        public CustomTypeException(String message, String detail, String errorCode, String customType,String extendedinfo, int entryLevel) {
054                super(message,"custom_type",customType);
055                setDetail(detail);
056                setErrorCode(errorCode);
057                if(extendedinfo!=null)setExtendedInfo(extendedinfo);
058                this.entryLevel=entryLevel;
059        }
060
061        
062
063        @Override
064        public StackTraceElement[] getStackTrace() {
065                List<StackTraceElement> list=new ArrayList<StackTraceElement>();
066                StackTraceElement[] elements = super.getStackTrace();
067                StackTraceElement element;
068                String template;
069                int level=0;
070                for(int i=0;i<elements.length;i++){
071                        element=elements[i];
072                        template = element.getFileName();
073                        if(level<entryLevel && (element.getLineNumber()<=0 || template==null || ResourceUtil.getExtension(template,"").equals("java"))) continue;
074                        if(++level>=entryLevel) {
075                                list.add(element);
076                        }
077                }
078                if(list.size()==0) return elements;
079                return list.toArray(new StackTraceElement[list.size()]);
080        }
081
082        @Override
083        public CatchBlock getCatchBlock(Config config) {
084                CatchBlock cb=super.getCatchBlock(config);
085                cb.setEL(KeyConstants._code,cb.get(KeyConstants._errorcode,null));
086                cb.setEL(KeyConstants._type,getCustomTypeAsString());
087                String ei=getExtendedInfo();
088                if(ei!=null)cb.setEL(KeyConstants._extended_info,ei);
089                //cb.setEL("ErrorCode","");
090                return cb;
091        }
092
093        @Override
094        public Struct getErrorBlock(PageContext pc, ErrorPage ep) {
095                Struct eb = super.getErrorBlock(pc, ep);
096                eb.setEL(KeyConstants._type,getCustomTypeAsString());
097                return eb;
098        }
099
100    @Override
101    public boolean typeEqual(String type) {
102        if(type==null) return true;
103        type=type.toLowerCase().trim();
104        if(type.equals("any")) return true;
105        
106        // Custom Type
107        if(getTypeAsString().equals("custom_type") || getTypeAsString().equals("customtype")) {
108            return compareCustomType(type,getCustomTypeAsString().toLowerCase().trim());
109        }
110        return super.typeEqual(type);
111    }
112    
113    /**
114     * @param leftType
115     * @param rightType
116     * @return is same custom type
117     */
118    private boolean compareCustomType(String leftType, String rightType) {
119        int left=leftType.length();
120        int right=rightType.length();
121        if(left>right) return false;
122        if(left==right) return leftType.equals(rightType);
123        
124        for(int i=0;i<left;i++) {
125            if(leftType.charAt(i)!=rightType.charAt(i)) return false;
126        }
127        return rightType.charAt(left)=='.';
128    }
129}