001    /*
002     * Copyright © 2008, 2012 Pedro Agulló Soliveres.
003     * 
004     * This file is part of DirectJNgine.
005     *
006     * DirectJNgine is free software: you can redistribute it and/or modify
007     * it under the terms of the GNU Lesser General Public License as published by
008     * the Free Software Foundation, either version 3 of the License.
009     *
010     * Commercial use is permitted to the extent that the code/component(s)
011     * do NOT become part of another Open Source or Commercially developed
012     * licensed development library or toolkit without explicit permission.
013     *
014     * DirectJNgine is distributed in the hope that it will be useful,
015     * but WITHOUT ANY WARRANTY; without even the implied warranty of
016     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
017     * GNU Lesser General Public License for more details.
018     *
019     * You should have received a copy of the GNU Lesser General Public License
020     * along with DirectJNgine.  If not, see <http://www.gnu.org/licenses/>.
021     * 
022     * This software uses the ExtJs library (http://extjs.com), which is 
023     * distributed under the GPL v3 license (see http://extjs.com/license).
024     */
025    
026    package com.softwarementors.extjs.djn.gson;
027    
028    import java.lang.reflect.Type;
029    
030    import com.google.gson.JsonParseException;
031    import com.softwarementors.extjs.djn.DirectJNgineException;
032    import com.softwarementors.extjs.djn.StringUtils;
033    import com.softwarementors.extjs.djn.api.RegisteredStandardMethod;
034    import com.softwarementors.extjs.djn.router.processor.ResponseData;
035    
036    public class JsonException extends DirectJNgineException {
037      private static final long serialVersionUID = 4992911540391211769L;
038    
039      private JsonException( String message, Throwable cause ) {
040        super(message, cause);
041        
042        assert !StringUtils.isEmpty(message);
043        assert cause != null;
044      }
045      
046      public static JsonException forFailedConversionFromResponseToJson(ResponseData response, Throwable ex) {
047        assert response != null;
048        assert ex != null;
049        
050        return new JsonException( "Failed attempt to convert a response to json. " + response.getFullLogDescription(), ex );
051      }
052    
053      public static JsonException forFailedConversionFromJsonStringToMethodParameters(RegisteredStandardMethod method, String jsonParametersString,
054        Class<?>[] parameterTypes, Type[] gsonParameterTypes, JsonParseException ex) 
055      {
056        assert method != null;
057        assert jsonParametersString != null;
058        assert parameterTypes != null;
059        assert ex != null;
060        
061        StringBuilder typeNames = getCommaSeparatedTypeNames(parameterTypes, gsonParameterTypes);
062        return new JsonException( "Failed attempt to convert from a json string to java method parameters. Method='" + method.getFullName() + "', Json string='" + 
063            jsonParametersString + "', ExpectedTypes='" + typeNames + "'", ex );
064      }
065    
066      private static StringBuilder getCommaSeparatedTypeNames(Class<?>[] parameterTypes, Type[] gsonParameterTypes) 
067      {
068        StringBuilder typeNames = new StringBuilder();
069        boolean hasGsonParametersTypes = gsonParameterTypes != null;
070        for( int i = 0; i < parameterTypes.length; i++  ) {
071          Class<?> type = parameterTypes[i];
072          typeNames.append( type.getName() );
073          if( hasGsonParametersTypes) {
074            assert gsonParameterTypes != null;
075            
076            Type gsonType = gsonParameterTypes[i];
077            if( gsonType != null) {
078              typeNames.append( " ::GENERIC= ");
079              typeNames.append( gsonType.toString());
080              typeNames.append( ":: ");
081            }
082          }
083    
084          boolean atEnd = i == parameterTypes.length - 1;
085          if( !atEnd ) {
086            typeNames.append( ", ");
087          }
088        }
089        
090        return typeNames;
091      }
092    }