001 /* 002 * Copyright © 2008, 2009 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 General Public License as published by 008 * the Free Software Foundation, either version 3 of the License. 009 * 010 * DirectJNgine 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 013 * GNU General Public License for more details. 014 * 015 * You should have received a copy of the GNU General Public License 016 * along with DirectJNgine. If not, see <http://www.gnu.org/licenses/>. 017 * 018 * This software uses the ExtJs library (http://extjs.com), which is 019 * distributed under the GPL v3 license (see http://extjs.com/license). 020 */ 021 022 package com.softwarementors.extjs.djn.api; 023 024 import java.lang.reflect.Method; 025 import java.util.List; 026 027 import com.softwarementors.extjs.djn.config.GlobalConfiguration; 028 import com.softwarementors.extjs.djn.config.RegisteredAction; 029 import com.softwarementors.extjs.djn.config.RegisteredApi; 030 import com.softwarementors.extjs.djn.config.RegisteredMethod; 031 import com.softwarementors.extjs.djn.config.RegisteredPollMethod; 032 import com.softwarementors.extjs.djn.router.PollRequestProcessor; 033 034 public class ApiCodeGenerator { 035 036 private static final String REMOTING_TYPE = "remoting"; 037 private RegisteredApi api; 038 private GlobalConfiguration globalConfiguration; 039 040 public ApiCodeGenerator( GlobalConfiguration globalConfiguration, RegisteredApi api ) { 041 assert globalConfiguration != null; 042 assert api != null; 043 044 this.globalConfiguration = globalConfiguration; 045 this.api = api; 046 } 047 048 private static final String TABS_1 = " "; 049 private static final String TABS_2 = " "; 050 private static final String TABS_3 = " "; 051 052 public void appendCode( StringBuilder result) { 053 assert result != null; 054 055 appendNamespaceAndProviderUrlSection(result); 056 appendPollingUrlsSection(result); 057 appendActionsSection(result); 058 } 059 060 private void appendNamespaceAndProviderUrlSection(StringBuilder result) { 061 assert result != null; 062 063 result.append( "Ext.namespace( '"); result.append( this.api.getNamespace()); result.append("');\n" ); 064 result.append('\n'); 065 result.append( this.api.getNamespace() ); result.append( ".PROVIDER_BASE_URL=" ); appendJsExpressionToGetBaseUrl(result); result.append( '\''); result.append( this.globalConfiguration.getProvidersUrl() ); result.append( "';"); 066 result.append('\n'); 067 result.append('\n'); 068 } 069 070 private void appendJsExpressionToGetBaseUrl(StringBuilder result) { 071 assert result != null; 072 073 result.append( "window.location.protocol + '//' + window.location.host + '/' + (window.location.pathname.split('/')[1]) + '/' + " ); 074 } 075 076 private void appendPollingUrlsSection(StringBuilder result) { 077 assert result != null; 078 079 result.append( this.api.getNamespace() ); result.append( ".POLLING_URLS = {\n"); 080 List<RegisteredPollMethod> pollMethods = this.api.getPollMethods(); 081 for( int i = 0; i < pollMethods.size(); i++ ) { 082 RegisteredPollMethod pollMethod = pollMethods.get(i); 083 boolean isLast = i == pollMethods.size() - 1; 084 appendPollUrl(result, pollMethod); 085 if( !isLast ) { 086 result.append( ", "); 087 } 088 result.append( "\n"); 089 } 090 result.append( "}\n"); 091 result.append( "\n"); 092 } 093 094 private void appendPollUrl(StringBuilder result, RegisteredPollMethod pollMethod) { 095 assert result != null; 096 assert pollMethod != null; 097 098 result.append( TABS_1 ); result.append( pollMethod.getName()); result.append( " : "); 099 result.append( this.api.getNamespace() ); result.append( ".PROVIDER_BASE_URL + " ); result.append( "'" ); result.append( PollRequestProcessor.PATHINFO_POLL_PREFIX); result.append( pollMethod.getName() ); result.append( "' " ); 100 if( getDebug() ) { 101 appendPollUrlExtraInformation(result, pollMethod); 102 } 103 } 104 105 private boolean getDebug() { 106 return this.globalConfiguration.getDebug(); 107 } 108 109 private void appendPollUrlExtraInformation(StringBuilder result, RegisteredPollMethod pollMethod) { 110 result.append( "/* "); appendMethodExtraInformation(pollMethod.getMethod(), pollMethod.getOwningClass(), false, result); 111 result.append( " -- calls "); result.append( pollMethod.getOwningClass().getName() ); result.append( "."); result.append( pollMethod.getMethod().getName() ); 112 result.append( " */"); 113 } 114 115 private void appendActionsSection(StringBuilder result) { 116 assert result != null; 117 118 appendActionsStart(result); 119 List<RegisteredAction> actions = this.api.getActions(); 120 121 // Need to filter out actions with no methods in order to avoid straw "," 122 /* 123 List<RegisteredAction> actionsWithMethods = new ArrayList<RegisteredAction>(); 124 for( RegisteredAction action : this.api.getActions() ) { 125 if( !action.getMethods().isEmpty() ) { 126 actionsWithMethods.add( action ); 127 } 128 } 129 */ 130 for( int i = 0; i < actions.size(); i++ ) { 131 boolean isLast = i == actions.size() - 1; 132 appendAction( actions.get(i), result, isLast ); 133 } 134 appendActionsEnd(result); 135 } 136 137 private void appendActionsStart( StringBuilder result ) { 138 assert result != null; 139 140 result.append( this.api.getNamespace() ); result.append( ".REMOTING_API"); result.append( " = {\n" ); 141 142 result.append(" url: " ); result.append( this.api.getNamespace() ); result.append( ".PROVIDER_BASE_URL") ; result.append( ",\n" ); 143 result.append(" type: '" ); result.append( REMOTING_TYPE ); result.append( "',\n" ); 144 result.append(" actions: {\n" ); 145 } 146 147 private void appendActionsEnd( StringBuilder result ) { 148 assert result != null; 149 150 result.append( " }\n" ); 151 result.append( "}\n" ); 152 result.append( '\n'); 153 /* 154 result.append( this.api.getNamespace()); result.append( ".registerProvider = function() {\n" ); 155 result.append( " var result = Ext.Direct.addProvider( " ); result.append( this.api.getNamespace() ); result.append( " );\n" ); 156 result.append( " return result;\n" ); 157 result.append("}\n" ); 158 */ 159 } 160 161 private void appendAction(RegisteredAction action, StringBuilder result, boolean isLast ) { 162 assert action != null; 163 assert result != null; 164 165 result.append( TABS_2 ); result.append( action.getName() ); result.append( ": [\n"); 166 167 List<RegisteredMethod> methods = action.getMethods(); 168 for( int i = 0; i < methods.size(); i++ ) { 169 boolean isLastMethod = i == methods.size() - 1; 170 appendMethod( methods.get(i), result, isLastMethod ); 171 } 172 173 result.append( TABS_2 ); result.append( "]" ); if( !isLast ) { result.append(","); } result.append('\n'); 174 } 175 176 private void appendMethod(RegisteredMethod method, StringBuilder result, boolean isLast) { 177 assert method != null; 178 assert result != null; 179 180 result.append( TABS_3 ); result.append( "{\n"); 181 result.append( TABS_3 ); result.append( " name: '"); result.append( method.getName() ); result.append( "'" ); appendMethodExtraInformation(method, result); result.append( ",\n"); 182 result.append( TABS_3 ); result.append( " len: "); result.append( method.getClientParameterCount() ); result.append( ",\n"); 183 result.append( TABS_3 ); result.append( " formHandler: "); result.append( method.getFormHandler() ); result.append( "\n"); 184 result.append( TABS_3 ); result.append( "}" ); if( !isLast ) { result.append(","); } result.append( '\n'); 185 } 186 187 private void appendMethodExtraInformation(RegisteredMethod method, StringBuilder result) { 188 assert method != null; 189 assert result != null; 190 191 if( getDebug() ) { 192 result.append( "/*"); 193 194 appendMethodExtraInformation( method.getMethod(), method.getActionClass(), !method.getFormHandler(), result ); 195 196 if( method.getFormHandler()) { 197 result.append( " -- FORM HANDLER"); 198 } 199 result.append( " */"); 200 } 201 } 202 203 private void appendMethodExtraInformation( Method method, Class<?> classOwningMethod, boolean logJavaParameterTypes, StringBuilder result ) { 204 assert method != null; 205 assert classOwningMethod != null; 206 assert result != null; 207 208 // Append parameters 209 result.append( "("); 210 if( logJavaParameterTypes ) { 211 Class<?>[] parameterTypes = method.getParameterTypes(); 212 for( int i=0; i < parameterTypes.length; i++ ) { 213 boolean isLast = i == parameterTypes.length - 1; 214 result.append( parameterTypes[i].getName() ); 215 if( !isLast ) { 216 result.append( ", "); 217 } 218 } 219 } 220 result.append( ")"); 221 222 // Append result type 223 Class<?> resultType = method.getReturnType(); 224 if( !resultType.equals(Void.class)) { 225 result.append( " => "); 226 result.append( resultType.getName()); 227 } 228 229 } 230 }