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, boolean minify) { 053 assert result != null; 054 055 appendNamespaceAndProviderUrlSection(result); 056 appendPollingUrlsSection(result, minify); 057 appendActionsSection(result, minify); 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, boolean minify) { 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, minify); 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, boolean minify) { 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( !minify ) { 101 appendPollUrlExtraInformation(result, pollMethod); 102 } 103 } 104 105 private void appendPollUrlExtraInformation(StringBuilder result, RegisteredPollMethod pollMethod) { 106 result.append( "/* "); appendMethodExtraInformation(pollMethod.getMethod(), pollMethod.getOwningClass(), false, result); 107 result.append( " -- calls "); result.append( pollMethod.getOwningClass().getName() ); result.append( "."); result.append( pollMethod.getMethod().getName() ); 108 result.append( " */"); 109 } 110 111 private void appendActionsSection(StringBuilder result, boolean minify) { 112 assert result != null; 113 114 appendActionsStart(result); 115 List<RegisteredAction> actions = this.api.getActions(); 116 117 for( int i = 0; i < actions.size(); i++ ) { 118 boolean isLast = i == actions.size() - 1; 119 appendAction( actions.get(i), result, isLast, minify ); 120 } 121 appendActionsEnd(result); 122 } 123 124 private void appendActionsStart( StringBuilder result ) { 125 assert result != null; 126 127 result.append( this.api.getNamespace() ); result.append( ".REMOTING_API"); result.append( " = {\n" ); 128 129 result.append(" url: " ); result.append( this.api.getNamespace() ); result.append( ".PROVIDER_BASE_URL") ; result.append( ",\n" ); 130 result.append(" type: '" ); result.append( REMOTING_TYPE ); result.append( "',\n" ); 131 result.append(" actions: {\n" ); 132 } 133 134 private void appendActionsEnd( StringBuilder result ) { 135 assert result != null; 136 137 result.append( " }\n" ); 138 result.append( "}\n" ); 139 result.append( '\n'); 140 } 141 142 private void appendAction(RegisteredAction action, StringBuilder result, boolean isLast, boolean minify ) { 143 assert action != null; 144 assert result != null; 145 146 result.append( TABS_2 ); result.append( action.getName() ); result.append( ": [\n"); 147 148 List<RegisteredMethod> methods = action.getMethods(); 149 for( int i = 0; i < methods.size(); i++ ) { 150 boolean isLastMethod = i == methods.size() - 1; 151 appendMethod( methods.get(i), result, isLastMethod, minify ); 152 } 153 154 result.append( TABS_2 ); result.append( "]" ); if( !isLast ) { result.append(","); } result.append('\n'); 155 } 156 157 private void appendMethod(RegisteredMethod method, StringBuilder result, boolean isLast, boolean minify) { 158 assert method != null; 159 assert result != null; 160 161 result.append( TABS_3 ); result.append( "{\n"); 162 result.append( TABS_3 ); result.append( " name: '"); result.append( method.getName() ); result.append( "'" ); 163 if( !minify ) { 164 appendMethodExtraInformation(method, result); 165 } 166 result.append( ",\n"); 167 result.append( TABS_3 ); result.append( " len: "); result.append( method.getClientParameterCount() ); result.append( ",\n"); 168 result.append( TABS_3 ); result.append( " formHandler: "); result.append( method.getFormHandler() ); result.append( "\n"); 169 result.append( TABS_3 ); result.append( "}" ); if( !isLast ) { result.append(","); } result.append( '\n'); 170 } 171 172 private void appendMethodExtraInformation(RegisteredMethod method, StringBuilder result) { 173 assert method != null; 174 assert result != null; 175 176 result.append( "/*"); 177 178 appendMethodExtraInformation( method.getMethod(), method.getActionClass(), !method.getFormHandler(), result ); 179 180 if( method.getFormHandler()) { 181 result.append( " -- FORM HANDLER"); 182 } 183 result.append( " */"); 184 } 185 186 private void appendMethodExtraInformation( Method method, Class<?> classOwningMethod, boolean writeJavaParameterTypes, StringBuilder result ) { 187 assert method != null; 188 assert classOwningMethod != null; 189 assert result != null; 190 191 // Append parameters 192 result.append( "("); 193 if( writeJavaParameterTypes ) { 194 Class<?>[] parameterTypes = method.getParameterTypes(); 195 for( int i=0; i < parameterTypes.length; i++ ) { 196 boolean isLast = i == parameterTypes.length - 1; 197 result.append( parameterTypes[i].getName() ); 198 if( !isLast ) { 199 result.append( ", "); 200 } 201 } 202 } 203 result.append( ")"); 204 205 // Append result type 206 Class<?> resultType = method.getReturnType(); 207 if( !resultType.equals(Void.class)) { 208 result.append( " => "); 209 result.append( resultType.getName()); 210 } 211 212 } 213 }