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 * 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 General Public License for more details. 018 * 019 * You should have received a copy of the GNU 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.jscodegen; 027 028 import java.lang.reflect.Method; 029 import java.util.List; 030 031 import com.softwarementors.extjs.djn.ClassUtils; 032 import com.softwarementors.extjs.djn.api.RegisteredAction; 033 import com.softwarementors.extjs.djn.api.RegisteredApi; 034 import com.softwarementors.extjs.djn.api.RegisteredMethod; 035 import com.softwarementors.extjs.djn.api.RegisteredPollMethod; 036 import com.softwarementors.extjs.djn.config.GlobalConfiguration; 037 import com.softwarementors.extjs.djn.router.processor.poll.PollRequestProcessor; 038 039 public class ApiCodeGenerator { 040 041 private static final String REMOTING_TYPE = "remoting"; 042 private RegisteredApi api; 043 private GlobalConfiguration globalConfiguration; 044 045 public ApiCodeGenerator( GlobalConfiguration globalConfiguration, RegisteredApi api ) { 046 assert globalConfiguration != null; 047 assert api != null; 048 049 this.globalConfiguration = globalConfiguration; 050 this.api = api; 051 } 052 053 private static final String TABS_1 = " "; 054 private static final String TABS_2 = " "; 055 private static final String TABS_3 = " "; 056 057 public void appendCode( StringBuilder result, boolean minify) { 058 assert result != null; 059 060 if( !minify ) { 061 result.append( "/**********************************************************************\n"); 062 result.append( " * \n"); 063 result.append( " * Code generated automatically by DirectJNgine\n"); 064 result.append( " * Copyright (c) 2009, Pedro Agulló Soliveres\n"); 065 result.append( " * \n"); 066 result.append( " * DO NOT MODIFY MANUALLY!!\n"); 067 result.append( " * \n"); 068 result.append( " **********************************************************************/\n"); 069 result.append( "\n"); 070 } 071 appendNamespaceAndProviderUrlSection(result); 072 appendPollingUrlsSection(result, minify); 073 appendActionsSection(result, minify); 074 } 075 076 private void appendNamespaceAndProviderUrlSection(StringBuilder result) { 077 assert result != null; 078 079 result.append( "Ext.namespace( '"); result.append( this.api.getApiNamespace()); result.append("');\n" ); 080 if( !this.api.getActionsNamespace().equals("")) { 081 result.append( "Ext.namespace( '"); result.append( this.api.getActionsNamespace()); result.append("');\n" ); 082 } 083 result.append('\n'); 084 result.append( this.api.getApiNamespace() ); result.append( ".PROVIDER_BASE_URL=" ); appendJsExpressionToGetBaseUrl(result); result.append( '\''); result.append( this.globalConfiguration.getProvidersUrl() ); result.append( "';"); 085 result.append('\n'); 086 result.append('\n'); 087 } 088 089 private void appendJsExpressionToGetBaseUrl(StringBuilder result) { 090 assert result != null; 091 092 result.append( "window.location.protocol + '//' + window.location.host + '/' + (window.location.pathname.split('/')[1]) + '/' + " ); 093 } 094 095 private void appendPollingUrlsSection(StringBuilder result, boolean minify) { 096 assert result != null; 097 098 result.append( this.api.getApiNamespace() ); result.append( ".POLLING_URLS = {\n"); 099 List<RegisteredPollMethod> pollMethods = this.api.getPollMethods(); 100 for( int i = 0; i < pollMethods.size(); i++ ) { 101 RegisteredPollMethod pollMethod = pollMethods.get(i); 102 boolean isLast = i == pollMethods.size() - 1; 103 appendPollUrl(result, pollMethod, minify); 104 if( !isLast ) { 105 result.append( ", "); 106 } 107 result.append( "\n"); 108 } 109 result.append( "}\n"); 110 result.append( "\n"); 111 } 112 113 private void appendPollUrl(StringBuilder result, RegisteredPollMethod pollMethod, boolean minify) { 114 assert result != null; 115 assert pollMethod != null; 116 117 result.append( TABS_1 ); result.append( pollMethod.getName()); result.append( " : "); 118 result.append( this.api.getApiNamespace() ); result.append( ".PROVIDER_BASE_URL + " ); result.append( "'" ); result.append( PollRequestProcessor.PATHINFO_POLL_PREFIX); result.append( pollMethod.getName() ); result.append( "' " ); 119 if( !minify ) { 120 appendPollUrlExtraInformation(result, pollMethod); 121 } 122 } 123 124 private void appendPollUrlExtraInformation(StringBuilder result, RegisteredPollMethod pollMethod) { 125 result.append( "/* "); appendMethodExtraInformation(pollMethod.getMethod(), pollMethod.getOwningClass(), false, result); 126 result.append( " -- calls "); result.append( ClassUtils.getNicePrintableName(pollMethod.getOwningClass()) ); result.append( "."); result.append( pollMethod.getMethod().getName() ); 127 result.append( " */"); 128 } 129 130 private void appendActionsSection(StringBuilder result, boolean minify) { 131 assert result != null; 132 133 appendActionsStart(result); 134 List<RegisteredAction> actions = this.api.getActions(); 135 136 for( int i = 0; i < actions.size(); i++ ) { 137 boolean isLast = i == actions.size() - 1; 138 appendAction( actions.get(i), result, isLast, minify ); 139 } 140 appendActionsEnd(result); 141 } 142 143 private void appendActionsStart( StringBuilder result ) { 144 assert result != null; 145 146 result.append( this.api.getApiNamespace() ); result.append( ".REMOTING_API"); result.append( " = {\n" ); 147 148 result.append(" url: " ); result.append( this.api.getApiNamespace() ); result.append( ".PROVIDER_BASE_URL") ; result.append( ",\n" ); 149 result.append(" type: '" ); result.append( REMOTING_TYPE ); result.append( "',\n" ); 150 if( !this.api.getActionsNamespace().equals("")) { 151 result.append( " namespace: " ); result.append( this.api.getActionsNamespace()); result.append( ",\n"); 152 } 153 result.append(" actions: {\n" ); 154 } 155 156 private void appendActionsEnd( StringBuilder result ) { 157 assert result != null; 158 159 result.append( " }\n" ); 160 result.append( "}\n" ); 161 result.append( '\n'); 162 } 163 164 private void appendAction(RegisteredAction action, StringBuilder result, boolean isLast, boolean minify ) { 165 assert action != null; 166 assert result != null; 167 168 result.append( TABS_2 ); result.append( action.getName() ); result.append( ": [\n"); 169 170 List<RegisteredMethod> methods = action.getMethods(); 171 for( int i = 0; i < methods.size(); i++ ) { 172 boolean isLastMethod = i == methods.size() - 1; 173 appendMethod( methods.get(i), result, isLastMethod, minify ); 174 } 175 176 result.append( TABS_2 ); result.append( "]" ); if( !isLast ) { result.append(","); } result.append('\n'); 177 } 178 179 private void appendMethod(RegisteredMethod method, StringBuilder result, boolean isLast, boolean minify) { 180 assert method != null; 181 assert result != null; 182 183 result.append( TABS_3 ); result.append( "{\n"); 184 result.append( TABS_3 ); result.append( " name: '"); result.append( method.getName() ); result.append( "'" ); 185 if( !minify ) { 186 appendMethodExtraInformation(method, result); 187 } 188 result.append( ",\n"); 189 result.append( TABS_3 ); result.append( " len: "); result.append( method.getClientParameterCount() ); result.append( ",\n"); 190 result.append( TABS_3 ); result.append( " formHandler: "); result.append( method.getFormHandler() ); result.append( "\n"); 191 result.append( TABS_3 ); result.append( "}" ); if( !isLast ) { result.append(","); } result.append( '\n'); 192 } 193 194 private void appendMethodExtraInformation(RegisteredMethod method, StringBuilder result) { 195 assert method != null; 196 assert result != null; 197 198 result.append( "/*"); 199 200 appendMethodExtraInformation( method.getMethod(), method.getActionClass(), !method.getFormHandler(), result ); 201 202 if( method.getFormHandler()) { 203 result.append( " -- FORM HANDLER"); 204 } 205 result.append( " */"); 206 } 207 208 private void appendMethodExtraInformation( Method method, Class<?> classOwningMethod, boolean writeJavaParameterTypes, StringBuilder result ) { 209 assert method != null; 210 assert classOwningMethod != null; 211 assert result != null; 212 213 // Append parameters 214 result.append( "("); 215 if( writeJavaParameterTypes ) { 216 Class<?>[] parameterTypes = method.getParameterTypes(); 217 for( int i=0; i < parameterTypes.length; i++ ) { 218 boolean isLast = i == parameterTypes.length - 1; 219 Class<?> cls = parameterTypes[i]; 220 result.append( ClassUtils.getNicePrintableName(cls) ); 221 if( !isLast ) { 222 result.append( ", "); 223 } 224 } 225 } 226 result.append( ")"); 227 228 // Append result type 229 Class<?> resultType = method.getReturnType(); 230 if( !resultType.equals(Void.class)) { 231 result.append( " => "); 232 result.append( ClassUtils.getNicePrintableName(resultType)); 233 } 234 235 } 236 }