diff --git a/common/src/main/java/com/genexus/db/DynamicExecute.java b/common/src/main/java/com/genexus/db/DynamicExecute.java index cd0c4dda3..0d7203731 100644 --- a/common/src/main/java/com/genexus/db/DynamicExecute.java +++ b/common/src/main/java/com/genexus/db/DynamicExecute.java @@ -26,7 +26,7 @@ public static String dynamicWebExecute(ModelContext context, int handle, Class s if (SpecificImplementation.DynamicExecute != null) isWebContext = SpecificImplementation.DynamicExecute.getIsWebContext(context); - if (isWebContext && c.getSuperclass().equals(SpecificImplementation.Application.getGXWebObjectStubClass())) + if (isWebContext && c.getSuperclass().getSuperclass().equals(SpecificImplementation.Application.getGXWebObjectStubClass())) { // Es un call a un webpanel String objetName; diff --git a/java/src/main/java/com/genexus/internet/GXWebProgressIndicator.java b/gxweb/src/main/java/com/genexus/internet/GXWebProgressIndicator.java similarity index 100% rename from java/src/main/java/com/genexus/internet/GXWebProgressIndicator.java rename to gxweb/src/main/java/com/genexus/internet/GXWebProgressIndicator.java diff --git a/java/src/main/java/com/genexus/internet/GXWebProgressIndicatorInfo.java b/gxweb/src/main/java/com/genexus/internet/GXWebProgressIndicatorInfo.java similarity index 100% rename from java/src/main/java/com/genexus/internet/GXWebProgressIndicatorInfo.java rename to gxweb/src/main/java/com/genexus/internet/GXWebProgressIndicatorInfo.java diff --git a/gxweb/src/main/java/com/genexus/internet/HttpAjaxContext.java b/gxweb/src/main/java/com/genexus/internet/HttpAjaxContext.java new file mode 100644 index 000000000..fd55ddc2b --- /dev/null +++ b/gxweb/src/main/java/com/genexus/internet/HttpAjaxContext.java @@ -0,0 +1,1778 @@ +package com.genexus.internet; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Array; +import java.util.*; + +import com.genexus.*; +import com.genexus.common.interfaces.IGXWebGrid; +import com.genexus.common.interfaces.IGXWindow; +import com.genexus.diagnostics.core.ILogger; +import com.genexus.diagnostics.core.LogManager; +import com.genexus.servlet.IServletContext; +import com.genexus.servlet.http.IHttpServletRequest; +import com.genexus.servlet.http.IHttpServletResponse; +import com.genexus.util.Codecs; +import com.genexus.util.Encryption; +import com.genexus.util.ThemeHelper; +import com.genexus.webpanels.DynAjaxEventContext; +import com.genexus.common.interfaces.IGXWebRow; + +import com.genexus.webpanels.HttpContextWeb; +import com.genexus.webpanels.WebUtils; +import json.org.json.IJsonFormattable; +import json.org.json.JSONArray; +import json.org.json.JSONException; +import json.org.json.JSONObject; + +public class HttpAjaxContext extends HttpContextWeb +{ + private static String GX_AJAX_REQUEST_HEADER = "GxAjaxRequest"; + + public static final int TYPE_RESET = 0; + public static final int TYPE_SUBMIT = 1; + public static final int TYPE_BUTTON = 2; + + public static final ILogger logger = LogManager.getLogger(HttpAjaxContext.class); + private JSONArray AttValues = new JSONArray(); + private JSONArray PropValues = new JSONArray(); + protected JSONObject HiddenValues = new JSONObject(); + protected JSONObject Messages = new JSONObject(); + private JSONObject WebComponents = new JSONObject(); + private Hashtable LoadCommands = new Hashtable<>(); + private ArrayList Grids = new ArrayList(); + private Hashtable DicGrids = new Hashtable(); + private JSONObject ComponentObjects = new JSONObject(); + protected GXAjaxCommandCollection commands = new GXAjaxCommandCollection(); + protected IGXWebRow _currentGridRow = null; + protected JSONArray StylesheetsToLoad = new JSONArray(); + private Vector styleSheets = new Vector<>(); + private boolean validEncryptedParm = true; + private Vector javascriptSources = new Vector<>(); + private Vector deferredFragments = new Vector(); + private HashSet deferredJavascriptSources = new HashSet(); + private String themekbPrefix; + private String themestyleSheet; + private String themeurlBuildNumber; + private Vector userStyleSheetFiles = new Vector(); + private String serviceWorkerFileName = "service-worker.js"; + private Boolean isServiceWorkerDefinedFlag = null; + private String webAppManifestFileName = "manifest.json"; + private Boolean isWebAppManifestDefinedFlag = null; + private boolean encryptionKeySended = false; + private boolean htmlHeaderClosed = false; + public boolean drawingGrid = false; + private static String CACHE_INVALIDATION_TOKEN; + + protected boolean bCloseCommand = false; + protected String formCaption = ""; + private Object[] returnParms = new Object[] {}; + private Object[] returnParmsMetadata = new Object[] {}; + + private Stack cmpContents = new Stack<>(); + + private String _ajaxOnSessionTimeout = "Ignore"; + public void setAjaxOnSessionTimeout( String ajaxOnSessionTimeout){ this._ajaxOnSessionTimeout = ajaxOnSessionTimeout;} + public String ajaxOnSessionTimeout(){ return _ajaxOnSessionTimeout;} + + DynAjaxEventContext dynAjaxEventContext = new DynAjaxEventContext(); + + public DynAjaxEventContext getDynAjaxEventContext() { + return dynAjaxEventContext; + } + + private boolean isJsOutputEnabled = true; + + public HttpAjaxContext(String requestMethod, IHttpServletRequest req, IHttpServletResponse res, + IServletContext servletContext) throws IOException { + super(requestMethod, req, res, servletContext); + } + + public HttpContext copy() { + try { + HttpAjaxContext ctx = new HttpAjaxContext(requestMethod, request, response, servletContext); + super.copyCommon(ctx); + + return ctx; + } catch (java.io.IOException e) { + return null; + } + } + + public void ajax_sending_grid_row(IGXWebRow row) { + if (isAjaxCallMode()) { + _currentGridRow = row; + } + else { + _currentGridRow = null; + } + } + + private void AddStyleSheetFile(String styleSheet, String urlBuildNumber, boolean isGxThemeHidden) + { + AddStyleSheetFile( styleSheet, urlBuildNumber, isGxThemeHidden, false); + } + + private void AddStyleSheetFile(String styleSheet, String urlBuildNumber, boolean isGxThemeHidden, boolean isDeferred) + { + if (!styleSheets.contains(styleSheet)) + { + styleSheets.add(styleSheet); + String sUncachedURL = oldConvertURL(styleSheet) + urlBuildNumber; + String sLayerName = styleSheet.replace("/", "_").replace(".","_"); + if (!this.getHtmlHeaderClosed() && this.isEnabled) + { + String sRelAtt = (isDeferred ? "rel=\"preload\" as=\"style\" " : "rel=\"stylesheet\""); + if (isGxThemeHidden) + writeTextNL(" @import url(\"" + sUncachedURL + "\") layer(" + sLayerName + ");"); + } + else + { + writeTextNL(" 0) + { + return true; + } + return false; + } + + private String getAjaxEncryptionKey() + { + if(getSessionValue(Encryption.AJAX_ENCRYPTION_KEY) == null) + { + if (!recoverEncryptionKey()) + { + webPutSessionValue(Encryption.AJAX_ENCRYPTION_KEY, Encryption.getRijndaelKey()); + } + } + return (String)getSessionValue(Encryption.AJAX_ENCRYPTION_KEY); + } + + private boolean recoverEncryptionKey() + { + if (getSessionValue(Encryption.AJAX_ENCRYPTION_KEY) == null) + { + String clientKey = getRequest().getHeader(Encryption.AJAX_SECURITY_TOKEN); + if (clientKey != null && clientKey.trim().length() > 0) + { + boolean candecrypt[]=new boolean[1]; + clientKey = Encryption.decryptRijndael(Encryption.GX_AJAX_PRIVATE_IV + clientKey, Encryption.GX_AJAX_PRIVATE_KEY, candecrypt); + if (candecrypt[0]) + { + webPutSessionValue(Encryption.AJAX_ENCRYPTION_KEY, clientKey); + return true; + }else + { + return false; + } + } + } + return false; + } + + public String DecryptAjaxCall(String encrypted) + { + validEncryptedParm = false; + if (isGxAjaxRequest()) + { + String key = getAjaxEncryptionKey(); + boolean candecrypt[] = new boolean[1]; + String decrypted = Encryption.decryptRijndael(encrypted, key, candecrypt); + validEncryptedParm = candecrypt[0]; + if (!validEncryptedParm) + { + CommonUtil.writeLogln( String.format("403 Forbidden error. Could not decrypt Ajax parameter: '%s' with key: '%s'", encrypted, key)); + sendResponseStatus(403, "Forbidden action"); + return ""; + } + if (validEncryptedParm && !getRequestMethod().equalsIgnoreCase("post")) + { + setQueryString(decrypted); + decrypted = GetNextPar(); + } + return decrypted; + } + return encrypted; + } + + public boolean IsValidAjaxCall() + { + return IsValidAjaxCall(true); + } + + public boolean IsValidAjaxCall(boolean insideAjaxCall) + { + if (insideAjaxCall && !validEncryptedParm) + { + CommonUtil.writeLogln( "Failed IsValidAjaxCall 403 Forbidden action"); + sendResponseStatus(403, "Forbidden action"); + return false; + } + else if (!insideAjaxCall && isGxAjaxRequest() && !isFullAjaxMode() && ajaxOnSessionTimeout().equalsIgnoreCase("Warn")) + { + sendResponseStatus(440, "Session timeout"); + return false; + } + return true; + } + + protected void ajax_addCmpContent( String content) + { + if (nCmpDrawLvl > 0) + (cmpContents.peek()).addContent(content); + } + + public void ajax_rspStartCmp( String CmpId) + { + if (isJsOutputEnabled) + { + try + { + WebComponents.put(CmpId, ""); + } + catch (JSONException ex) { } + } + nCmpDrawLvl++; + cmpContents.push(new GXCmpContent(CmpId)); + } + + public void ajax_rspEndCmp() + { + nCmpDrawLvl--; + try + { + GXCmpContent cmp = cmpContents.pop(); + WebComponents.put(cmp.getId(), cmp.getContent()); + if (isSpaRequest()) + { + if (nCmpDrawLvl > 0) + (cmpContents.peek()).addContent(cmp.getContent()); + } + } + catch (JSONException ex) + { + } + } + + private void sendReferer() + { + ajax_rsp_assign_hidden("sCallerURL", org.owasp.encoder.Encode.forUri(getReferer())); + } + + protected void addNavigationHidden() + { + if (this.isLocalStorageSupported()) + { + try { + HiddenValues.put("GX_CLI_NAV", "true"); + } catch (JSONException e) { + } + GXNavigationHelper nav = this.getNavigationHelper(); + if (nav.count() > 0) + { + String sUrl = this.getRequestNavUrl().trim(); + String popupLevel = nav.getUrlPopupLevel(sUrl); + try { + HiddenValues.put("GX_NAV", nav.toJSonString(popupLevel)); + } catch (JSONException e) { + } + nav.deleteStack(popupLevel); + } + } + } + + public void SendWebComponentState() + { + AddStylesheetsToLoad(); + } + + public void SendState() + { + sendReferer(); + sendWebSocketParms(); + addNavigationHidden(); + AddThemeHidden(this.getTheme()); + AddStylesheetsToLoad(); + if (isSpaRequest()) + { + writeTextNL(""); + } + else + { + if (drawGridsAtServer()) + { + writeTextNL(""); + } + skipLines(1); + String value = HiddenValues.toString(); + if (useBase64ViewState()) + { + try{ + value = Codecs.base64Encode(value, "UTF8"); + }catch(Exception ex){} + writeTextNL(""); + } + writeText("
"); + } + } + + private void sendWebSocketParms() + { + if (!this.isAjaxRequest() || isSpaRequest()) + { + ajax_rsp_assign_hidden("GX_WEBSOCKET_ID", clientId); + } + } + + public void AddDeferredJavascriptSource(String jsSrc, String urlBuildNumber) + { + deferredJavascriptSources.add(oldConvertURL(jsSrc) + urlBuildNumber); + } + + + private String FetchCustomCSS() + { + String cssContent; + cssContent = ApplicationContext.getcustomCSSContent().get(getRequest().getServletPath()); + if (cssContent == null) + { + String path = getRequest().getServletPath().replaceAll(".*/", "") + ".css"; + try(InputStream istream = context.packageClass.getResourceAsStream(path)) + { + + if (istream == null) + { + cssContent = ""; + } + else { + //BOMInputStream bomInputStream = new BOMInputStream(istream);// Avoid using BOMInputStream because of runtime error (java.lang.NoSuchMethodError: org.apache.commons.io.IOUtils.length([Ljava/lang/Object;)I) issue 94611 + //cssContent = IOUtils.toString(bomInputStream, "UTF-8"); + cssContent = PrivateUtilities.BOMInputStreamToStringUTF8(istream); + } + } + catch ( Exception e) { + cssContent = ""; + } + ApplicationContext.getcustomCSSContent().put(getRequest().getServletPath(), cssContent); + } + return cssContent; + } + + public void CloseStyles() + { + String cssContent = FetchCustomCSS(); + boolean bHasCustomContent = ! cssContent.isEmpty(); + if (bHasCustomContent && !styleSheets.contains(getRequest().getServletPath())) + { + writeTextNL(""); + styleSheets.add(getRequest().getServletPath()); + } + String[] referencedFiles = ThemeHelper.getThemeCssReferencedFiles(PrivateUtilities.removeExtension(themestyleSheet)); + for (int i=0; i vEnum = deferredFragments.elements(); + while(vEnum.hasMoreElements()) + { + writeTextNL(vEnum.nextElement()); + } + } + + public void ClearJavascriptSources() { + javascriptSources.clear(); + } + + public void AddJavascriptSource(String jsSrc, String urlBuildNumber, boolean userDefined, boolean isInlined) + { + if(!javascriptSources.contains(jsSrc)) + { + urlBuildNumber = getURLBuildNumber(jsSrc, urlBuildNumber); + javascriptSources.add(jsSrc); + String queryString = urlBuildNumber; + String attributes = ""; + if (userDefined) + { + queryString = ""; + attributes = "data-gx-external-script"; + } + String fragment = "" ; + if (isAjaxRequest() || isInlined || jsSrc == "jquery.js" || jsSrc == "gxcore.js") + { + writeTextNL(fragment); + } + else + { + deferredFragments.add(fragment); + } + // After including jQuery, include all the deferred Javascript files + if (jsSrc.equals("jquery.js")) + { + for (String deferredJsSrc : deferredJavascriptSources) + { + AddJavascriptSource(deferredJsSrc, "", false, true); + } + } + // After including gxgral, set the Service Worker Url if one is defined + if (jsSrc.equals("gxgral.js") && isServiceWorkerDefined()) + { + writeTextNL(""); + } + } + } + + public void addWebAppManifest() + { + if (isWebAppManifestDefined()) + { + writeTextNL(""); + } + } + + private boolean isServiceWorkerDefined() + { + if (isServiceWorkerDefinedFlag == null) + { + isServiceWorkerDefinedFlag = Boolean.valueOf(checkFileExists(serviceWorkerFileName)); + } + return isServiceWorkerDefinedFlag == Boolean.valueOf(true); + } + + private boolean isWebAppManifestDefined() + { + if (isWebAppManifestDefinedFlag == null) + { + isWebAppManifestDefinedFlag = Boolean.valueOf(checkFileExists(webAppManifestFileName)); + } + return isWebAppManifestDefinedFlag == Boolean.valueOf(true); + } + + private boolean checkFileExists(String fileName) + { + boolean fileExists = false; + try + { + File file = new File(getDefaultPath() + staticContentBase + fileName); + fileExists = file.exists() && file.isFile(); + com.genexus.diagnostics.Log.info("Searching if file exists (" + fileName + "). Found: " + String.valueOf(fileExists)); + } + catch (Exception e) + { + fileExists = false; + com.genexus.diagnostics.Log.info("Failed searching for a file (" + fileName + ")"); + } + return fileExists; + } + + public void SendAjaxEncryptionKey() + { + if(!encryptionKeySended) + { + String key = getAjaxEncryptionKey(); + ajax_rsp_assign_hidden(Encryption.AJAX_ENCRYPTION_KEY, key); + ajax_rsp_assign_hidden(Encryption.AJAX_ENCRYPTION_IV, Encryption.GX_AJAX_PRIVATE_IV); + try + { + ajax_rsp_assign_hidden(Encryption.AJAX_SECURITY_TOKEN, Encryption.encryptRijndael(key, Encryption.GX_AJAX_PRIVATE_KEY)); + } + catch(Exception exc) {} + encryptionKeySended = true; + } + } + + public void SendServerCommands() + { + try { + if (!isAjaxRequest() && commands.getCount() > 0) + { + HiddenValues.put("GX_SRV_COMMANDS", commands.getJSONArray()); + } + } + catch (JSONException e) { + } + } + + public void ajax_rsp_assign_prop_as_hidden(String Control, String Property, String Value) + { + if (!this.isAjaxRequest()) + { + ajax_rsp_assign_hidden(Control + "_" + Property.substring(0, 1) + Property.substring(1).toLowerCase(), Value); + } + } + + public boolean IsSameComponent(String oldName, String newName) + { + if(oldName.trim().equalsIgnoreCase(newName.trim())) + { + return true; + } + else + { + if(newName.trim().toLowerCase().startsWith(oldName.trim().toLowerCase() + "?")) + { + return true; + } + else + { + String packageName = context.getPackageName(); + String qoldName; + String qnewName; + + if ( (oldName.indexOf(packageName) != 0) || (newName.indexOf(packageName) != 0)) + { + qoldName = (oldName.indexOf(packageName) != 0) ? packageName + "." + oldName : oldName; + qnewName = (newName.indexOf(packageName) != 0) ? packageName + "." + newName : newName; + return IsSameComponent(qoldName, qnewName); + } + } + } + return false; + } + + private JSONObject getGxObject(JSONArray array, String CmpContext, boolean IsMasterPage) + { + try + { + JSONObject obj; + int len = array.length(); + for(int i=0; i= 0) + return; + } + if (Control.equals("FORM") && Property.equals("Caption")) + { + formCaption = Value; + } + JSONObject obj = getGxObject(PropValues, CmpContext, IsMasterPage); + if (obj != null) + { + JSONObject ctrlProps = getControlProps(obj, Control); + if (ctrlProps != null) + { + ctrlProps.put(Property, Value); + } + } + com.genexus.internet.HttpContext webContext = (HttpContext) com.genexus.ModelContext.getModelContext().getHttpContext(); + if (webContext != null && !webContext.isAjaxRequest()) + { + ajax_rsp_assign_hidden(Control + "_" + Property.substring(0, 1) + Property.substring(1).toLowerCase(), Value); + } + } + catch (JSONException e) { + } + } + } + } + + public void ajax_rsp_assign_uc_prop(String CmpContext, boolean IsMasterPage, String Control, String Property, String Value) + { + ajax_rsp_assign_prop(CmpContext, IsMasterPage, Control, Property, Value, true); + ajax_rsp_assign_prop_as_hidden(Control, Property, Value); + } + + public void ajax_rsp_assign_boolean_hidden(String Property, Boolean Value) + { + ajax_rsp_assign_hidden(Property, (Object)Value); + } + + public void ajax_rsp_assign_hidden(String Property, String Value) + { + ajax_rsp_assign_hidden(Property, (Object)Value); + } + + private void ajax_rsp_assign_hidden(String Property, Object Value) + { + try { + if (_currentGridRow != null) + _currentGridRow.AddHidden(Property, Value); + else + HiddenValues.put(Property, Value); + } + catch (JSONException e) { + } + } + + public void ajax_rsp_assign_hidden_sdt( String SdtName, Object SdtObj) + { + try { + if (SdtObj instanceof IGxJSONAble) + { + HiddenValues.put(SdtName, ((IGxJSONAble)SdtObj).GetJSONObject()); + } + else + { + if (SdtObj.getClass().isArray()) + { + try { + HiddenValues.put(SdtName, ObjArrayToJSONArray(SdtObj)); + } + catch(ClassCastException e){ + logger.error(String.format("Could not serialize Object '%s' to JSON", SdtName), e); + HiddenValues.put(SdtName, SdtObj); + } + } + } + } + catch (JSONException e) { + logger.error(String.format("Could not serialize Object '%s' to JSON", SdtName), e); + } + } + + public void ajax_rsp_assign_grid(String gridName, IGXWebGrid gridObj) + { + Object jsonObj = ((IGxJSONAble) gridObj).GetJSONObject(); + Grids.add(jsonObj); + } + + public void ajax_rsp_assign_grid(String gridName, IGXWebGrid gridObj, String Control) + { + Object jsonObj = ((IGxJSONAble) gridObj).GetJSONObject(); + if (DicGrids.containsKey(Control)) { + Grids.set(DicGrids.get(Control), jsonObj); + } + else + { + Grids.add(jsonObj); + DicGrids.put(Control, Grids.size() - 1); + } + } + + public void ajax_rsp_clear(){ + PropValues = new JSONArray(); + } + + private boolean shouldLogAjaxControlProperty(String property) + { + return isJsOutputEnabled || (isSpaRequest() && property == "Enabled"); + } + + @Deprecated + public void AddComponentObject(String cmpCtx, String objName) + { + AddComponentObject(cmpCtx, objName, true); + } + + public void AddComponentObject(String cmpCtx, String objName, boolean justCreated) + { + try { + com.genexus.internet.HttpContext webContext = (HttpContext) com.genexus.ModelContext.getModelContext().getHttpContext(); + if (justCreated) + { + try { + webContext.DeletePostValuePrefix(cmpCtx); + } + catch (Exception e) { + logger.error("Could not delete post value prefix", e); + } + } + ComponentObjects.put(cmpCtx, objName); + } + catch (JSONException e) { + } + } + + public void SendComponentObjects() + { + try { + HiddenValues.put("GX_CMP_OBJS", ComponentObjects); + } + catch (JSONException e) { + } + } + + protected void AddThemeHidden(String theme) + { + try { + HiddenValues.put("GX_THEME", theme); + } + catch (JSONException e) { + } + } + + public void AddStylesheetsToLoad() + { + if (StylesheetsToLoad.length() > 0) + { + try { + HiddenValues.put("GX_STYLE_FILES", StylesheetsToLoad); + } + catch (JSONException e) { + } + } + } + + public void SaveComponentMsgList( String sPrefix) + { + try { + Messages.put(sPrefix, GX_msglist.GetJSONObject()); + } + catch (JSONException e) { + } + } + + public String getJSONContainerResponse(IGxJSONAble Container) { + + GXJSONObject jsonCmdWrapper = new GXJSONObject(isMultipartContent()); + try + { + jsonCmdWrapper.put("gxHiddens", HiddenValues); + jsonCmdWrapper.put("gxContainer", Container.GetJSONObject()); + } + catch (JSONException e) + { + } + return jsonCmdWrapper.toString(); + } + + protected String getJSONResponsePrivate(String cmpContext) + { + GXJSONObject jsonCmdWrapper = new GXJSONObject(isMultipartContent()); + try + { + Collections.reverse(Arrays.asList(Grids)); + JSONArray JSONGrids = new JSONArray(Grids); + if (commands.AllowUIRefresh()) + { + if (cmpContext == null || cmpContext.equals("")) + { + cmpContext = "MAIN"; + } + SaveComponentMsgList(cmpContext); + jsonCmdWrapper.put("gxProps", PropValues); + jsonCmdWrapper.put("gxHiddens", HiddenValues); + jsonCmdWrapper.put("gxValues", AttValues); + jsonCmdWrapper.put("gxMessages", Messages); + jsonCmdWrapper.put("gxComponents", WebComponents); + jsonCmdWrapper.put("gxGrids", JSONGrids); + } + for(Enumeration loadCmds = LoadCommands.keys(); loadCmds.hasMoreElements();) + { + appendAjaxCommand("load", LoadCommands.get(loadCmds.nextElement())); + } + if (commands.getCount() > 0) + { + jsonCmdWrapper.put("gxCommands", commands.getJSONArray()); + } + } + catch (JSONException e) + { + } + return jsonCmdWrapper.toString(); + } + + public String getJSONResponse(String cmpContext) + { + if (isCloseCommand() || isRedirected()) + return ""; + return getJSONResponsePrivate(cmpContext); + } + + public String getJSONResponse() + { + return getJSONResponse(""); + } + + public static Object[] createArrayFromArrayObject(Object o) { + if(!o.getClass().getComponentType().isPrimitive()) + return (Object[])o; + + int element_count = Array.getLength(o); + Object elements[] = new Object[element_count]; + + for(int i = 0; i < element_count; i++){ + elements[i] = Array.get(o, i); + } + + return elements; + } + + public static JSONArray ObjArrayToJSONArray(Object parms) + { + return ObjArrayToJSONArray(createArrayFromArrayObject(parms)); + } + + public static JSONArray ObjArrayToJSONArray(Object[] parms) + { + JSONArray inputs = new JSONArray(); + for (int i = 0; i < parms.length; i++) + { + Object parm = parms[i]; + if (parm instanceof IGxJSONAble) + { + inputs.put(((IGxJSONAble)parm).GetJSONObject()); + } + else if (parm.getClass().isArray()) + { + inputs.put(ObjArrayToJSONArray((Object[])parm)); + } + else + { + inputs.put(parm); + } + } + return inputs; + } + + public String getWebReturnParmsJS() + { + return ObjArrayToJSONArray(this.getWebReturnParms()).toString(); + } + + public String getWebReturnParmsMetadataJS() + { + return ObjArrayToJSONArray(this.getWebReturnParmsMetadata()).toString(); + } + + public void writeText(String text) + { + if (getResponseCommited()) + return; + if (isEnabled == false) + { + ajax_addCmpContent(text); + return; + } + _writeText(text); + } + + public void writeValueComplete(String text) + { + writeValueComplete(text, true, true, true); + } + + public void writeValueSpace(String text) + { + writeValueComplete(text, false, false, true); + } + + public void writeValueEnter(String text) + { + writeValueComplete(text, false, true, false); + } + + /** Este writeValue tiene en consideracion los espacios consecutivos, + * los enter y los tabs + */ + public void writeValueComplete(String text, boolean cvtTabs, boolean cvtEnters, boolean cvtSpaces) + { + StringBuilder sb = new StringBuilder(); + boolean lastCharIsSpace = true; // Asumo que al comienzo el lastChar era space + for (int i = 0; i < text.length(); i++) + { + char currentChar = text.charAt(i); + switch (currentChar) + { + case (char) 34: + sb.append("""); + break; + case (char) 38: + sb.append("&"); + break; + case (char) 60: + sb.append("<"); + break; + case (char) 62: + sb.append(">"); + break; + case '\t': + sb.append(cvtTabs ? "    " : ("" + currentChar)); + break; + case '\r': + if (cvtEnters && text.length() > i + 1 && text.charAt(i+1) == '\n'){ + sb.append(cvtEnters ? "
" : ("" + currentChar)); + i++; + } + break; + case '\n': + sb.append(cvtEnters ? "
" : ("" + currentChar)); + break; + case ' ': + sb.append((lastCharIsSpace && cvtSpaces) ? " " : " "); + break; + default: + sb.append("" + currentChar); + } + lastCharIsSpace = currentChar == ' '; + } + writeText(sb.toString()); + } + + public void writeValue(String text) + { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < text.length(); i++) + { + char currentChar = text.charAt(i); + + switch (currentChar) + { + case '"': + sb.append("""); + break; + case '&': + sb.append("&"); + break; + case '<': + sb.append("<"); + break; + case '>': + sb.append(">"); + break; + default: + sb.append(currentChar); + } + } + writeText(sb.toString()); + } + + public void skipLines(long num) + { + for(; num > 0; num --) + { + writeText("\n"); + } + } + + public void writeTextNL(String text) + { + writeText(text + "\n"); + } + + public void ajax_rsp_command_close() { + bCloseCommand = true; + try { + JSONObject closeParms = new JSONObject(); + closeParms.put("values", ObjArrayToJSONArray(this.getWebReturnParms())); + closeParms.put("metadata", ObjArrayToJSONArray(this.getWebReturnParmsMetadata())); + appendAjaxCommand("close", closeParms); + } catch (JSONException ex) { + } + } + + public boolean getHtmlHeaderClosed() { + return this.htmlHeaderClosed; + } + + public void closeHtmlHeader() { + this.htmlHeaderClosed = true; + this.writeTextNL(""); + } + + public void redirect_impl(String url, IGXWindow win) { + if (!isGxAjaxRequest() && !isAjaxRequest() && win == null) { + String popupLvl = getNavigationHelper(false).getUrlPopupLevel(getRequestNavUrl()); + String popLvlParm = ""; + if (popupLvl != "-1") { + popLvlParm = (url.indexOf('?') != -1) ? (useOldQueryStringFormat? "," : "&") : "?"; + popLvlParm += com.genexus.util.Encoder.encodeURL("gxPopupLevel=" + popupLvl + ";"); + } + + if (isSpaRequest(true)) { + pushUrlSessionStorage(); + getResponse().setHeader(GX_SPA_REDIRECT_URL, url + popLvlParm); + sendCacheHeaders(); + } else { + redirect_http(url + popLvlParm); + } + } else { + + try { + if (win != null) { + appendAjaxCommand("popup", win.GetJSONObject()); + } else if (!Redirected) { + JSONObject jsonCmd = new JSONObject(); + jsonCmd.put("url", url); + if (this.wjLocDisableFrm > 0) { + jsonCmd.put("forceDisableFrm", this.wjLocDisableFrm); + } + appendAjaxCommand("redirect", jsonCmd); + if (isGxAjaxRequest()) + dispatchAjaxCommands(); + Redirected = true; + } + } catch (JSONException e) { + redirect_http(url); + } + } + } + + public void dispatchAjaxCommands() { + Boolean isResponseCommited = getResponseCommited(); + if (!getResponseCommited()) { + String res = getJSONResponsePrivate(""); + if (!isMultipartContent()) { + response.setContentType("application/json"); + } + sendFinalJSONResponse(res); + setResponseCommited(); + } + } + + public void sendFinalJSONResponse(String json) { + boolean isMultipartResponse = !getResponseCommited() && isMultipartContent(); + if (isMultipartResponse) { + _writeText( + ""); + } + + public void setDrawingGrid(boolean drawingGrid) + { + this.drawingGrid = drawingGrid; + } + + public void windowClosed() + { + String popupLevel = getNavigationHelper().getUrlPopupLevel(getRequestNavUrl()); + if (popupLevel.equals("-1")) + popReferer(); + else + deleteReferer(popupLevel); + } + + public boolean isPopUpObject() + { + if (wrapped) + return false; + return !getNavigationHelper().getUrlPopupLevel(getRequestNavUrl()).equals("-1"); + } + + public int getButtonType() + { + if (drawGridsAtServer()) + { + return TYPE_SUBMIT; + } + return TYPE_BUTTON; + } + + public boolean drawGridsAtServer() + { + if (drawGridsAtServer == -1) + { + drawGridsAtServer = 0; + if( (getContext().getPreferences()).propertyExists("DrawGridsAtServer")) + { + String prop = (getContext().getPreferences()).getProperty("DrawGridsAtServer", "no"); + if (prop.equalsIgnoreCase("always")) + { + drawGridsAtServer = 1; + } + else if (prop.equalsIgnoreCase("ie6")) + { + if (getBrowserType() == BROWSER_IE) + { + if (getBrowserVersion().startsWith("6")) + { + drawGridsAtServer = 1; + } + } + } + } + } + return (drawGridsAtServer == 1); + } + + public String getCssProperty(String propName, String propValue) + { + int browserType = getBrowserType(); + if (propName.equalsIgnoreCase("align")) + { + if (browserType == BROWSER_FIREFOX) + { + return "-moz-" + propValue; + } + else if (browserType == BROWSER_CHROME || browserType == BROWSER_SAFARI) + { + return "-khtml-" + propValue; + } + } + return propValue; + } + + public byte isMobileBrowser() + { + String accept = getHeader("HTTP_ACCEPT"); + + return (accept.indexOf("wap") >= 0 || accept.indexOf("hdml") >= 0)?0: (byte) 1; + } + + public String htmlEndTag(HTMLElement element) + { + HTMLDocType docType = context.getClientPreferences().getDOCTYPE(); + if ((docType == HTMLDocType.HTML4 || docType == HTMLDocType.NONE || docType == HTMLDocType.HTML4S) && + (element == HTMLElement.IMG || + element == HTMLElement.INPUT || + element == HTMLElement.META || + element == HTMLElement.LINK)) + return ">"; + else if (element == HTMLElement.OPTION) + if (docType == HTMLDocType.XHTML1 || docType == HTMLDocType.HTML5) + return ""; + else + return ""; + else + return "/>"; + } + + public String htmlDocType() + { + HTMLDocType docType = context.getClientPreferences().getDOCTYPE(); + switch (docType) + { + case HTML4: + if (context.getClientPreferences().getDOCTYPE_DTD()) + return ""; + else + return ""; + case HTML4S: + if (context.getClientPreferences().getDOCTYPE_DTD()) + return ""; + else + return ""; + case XHTML1: + if (context.getClientPreferences().getDOCTYPE_DTD()) + return ""; + else + return ""; + case HTML5: return ""; + default: return ""; + } + } + + public void popReferer() + { + getNavigationHelper().popUrl(getRequestNavUrl()); + } + + public String getCacheInvalidationToken() + { + if (CACHE_INVALIDATION_TOKEN == null || CACHE_INVALIDATION_TOKEN.trim().length() == 0) + { + String token = (context.getPreferences()).getProperty("CACHE_INVALIDATION_TOKEN", ""); + if (token == null || token.trim().length() == 0) + { + CACHE_INVALIDATION_TOKEN = new java.text.DecimalFormat("#").format(CommonUtil.random() * 1000000); + } + else + { + CACHE_INVALIDATION_TOKEN = token; + } + } + return CACHE_INVALIDATION_TOKEN; + } + + class GXCmpContent + { + private String id; + private String content; + + public GXCmpContent(String id) + { + this.id = id; + this.content = ""; + } + + public String getId() + { + return id; + } + + public void addContent(String content) + { + this.content += content; + } + + public String getContent() + { + return content; + } + } + + class GXAjaxCommand + { + private String[] canManyCmds = new String[] { "print", "load", "popup", "refresh", "ucmethod", "cmp_refresh", "addlines", "set_focus", "calltarget", "exoprop", "exomethod", "refresh_form" }; + private String type; + private Object data; + + public GXAjaxCommand(String type) + { + this.type = type; + this.data = ""; + } + + public GXAjaxCommand(String type, Object data) + { + this.type = type; + this.data = data; + } + + public String getType() + { + return type; + } + + public void setData(Object data) + { + this.data = data; + } + + public Object getData() + { + return data; + } + + public JSONObject getJSONObject() + { + JSONObject jObj = new JSONObject(); + try { + jObj.put(type, data); + } catch (JSONException ex) { + } + return jObj; + } + + public boolean canHaveMany() + { + for (int i = 0; i < canManyCmds.length; i++) + { + if (type.equals(canManyCmds[i])) + { + return true; + } + } + return false; + } + + public boolean equals(Object obj) + { + if (obj instanceof GXAjaxCommand) + { + if (!canHaveMany()) + { + return (type.equalsIgnoreCase(((GXAjaxCommand)obj).getType())); + } + } + return super.equals(obj); + } + + public String toString() + { + return "{ type:" + type + ", data:" + data + " }"; + } + } + + public class GXUsercontrolMethod implements IGxJSONAble + { + JSONObject wrapper; + + public GXUsercontrolMethod(String CmpContext, boolean IsMasterPage, String containerName, String methodName, String output, Object[] parms) + { + wrapper = new JSONObject(); + AddObjectProperty("CmpContext", CmpContext); + AddObjectProperty("IsMasterPage", new Boolean(IsMasterPage)); + AddObjectProperty("Control", containerName); + AddObjectProperty("Method", methodName); + AddObjectProperty("Output", output); + AddObjectProperty("Parms", HttpAjaxContext.ObjArrayToJSONArray(parms)); + } + + public JSONArray GetParmsJArray(Object[] parms) + { + JSONArray inputs = new JSONArray(); + for (int i = 0; i < parms.length; i++) + { + Object parm = parms[i]; + if (parm instanceof IGxJSONAble) + { + inputs.put(((IGxJSONAble)parm).GetJSONObject()); + } + else + { + inputs.put(parm); + } + } + return inputs; + } + + public void AddObjectProperty(String name, Object prop) + { + try + { + wrapper.put(name, prop); + } catch (JSONException ex) { + } + } + + public Object GetJSONObject(boolean includeState) + { + return GetJSONObject(); + } + + public Object GetJSONObject() + { + return wrapper; + } + + public void FromJSONObject(IJsonFormattable obj) + { + } + + public String ToJavascriptSource() + { + return wrapper.toString(); + } + + public void tojson() + { + } + } + + class GXAjaxCommandCollection + { + private ArrayList commands; + private boolean allowUIRefresh; + + public GXAjaxCommandCollection() + { + commands = new ArrayList<>(); + allowUIRefresh = true; + } + + public int getCount() + { + return commands.size(); + } + + public boolean AllowUIRefresh() + { + return allowUIRefresh; + } + + public void AppendCommand(GXAjaxCommand cmd) + { + GXAjaxCommand cmd1 = GetCommand(cmd); + if (cmd1 == null) + { + if (allowUIRefresh) + { + allowUIRefresh = cmd.canHaveMany(); + } + commands.add(cmd); + } + else + { + cmd1.setData(cmd.getData()); + } + } + + private GXAjaxCommand GetCommand(GXAjaxCommand cmd) + { + int cIdx = commands.indexOf(cmd); + if (cIdx > 0) + { + return commands.get(cIdx); + } + return null; + } + + public JSONArray getJSONArray() + { + JSONArray jArr = new JSONArray(); + for(int i=0; i '%s' %s", token.get_issuer(), issuer, lsep)); } - if (!StripInvalidChars(value).equals(StripInvalidChars(token.get_value()))) { + if (!GXutil.StripInvalidChars(value).equals(GXutil.StripInvalidChars(token.get_value()))) { stringBuilder.append(String.format("Verify: value mismatch '%s' <> '%s' %s", token.get_value(), value, lsep)); } if (!(new Date().compareTo(token.get_expiration()) < 0)) { diff --git a/java/src/main/java/com/genexus/security/web/jose/jwt/Algorithm.java b/gxweb/src/main/java/com/genexus/security/web/jose/jwt/Algorithm.java similarity index 100% rename from java/src/main/java/com/genexus/security/web/jose/jwt/Algorithm.java rename to gxweb/src/main/java/com/genexus/security/web/jose/jwt/Algorithm.java diff --git a/java/src/main/java/com/genexus/security/web/jose/jwt/JWTAlgorithmException.java b/gxweb/src/main/java/com/genexus/security/web/jose/jwt/JWTAlgorithmException.java similarity index 100% rename from java/src/main/java/com/genexus/security/web/jose/jwt/JWTAlgorithmException.java rename to gxweb/src/main/java/com/genexus/security/web/jose/jwt/JWTAlgorithmException.java diff --git a/java/src/main/java/com/genexus/security/web/jose/jwt/JWTAudienceException.java b/gxweb/src/main/java/com/genexus/security/web/jose/jwt/JWTAudienceException.java similarity index 100% rename from java/src/main/java/com/genexus/security/web/jose/jwt/JWTAudienceException.java rename to gxweb/src/main/java/com/genexus/security/web/jose/jwt/JWTAudienceException.java diff --git a/java/src/main/java/com/genexus/security/web/jose/jwt/JWTExpiredException.java b/gxweb/src/main/java/com/genexus/security/web/jose/jwt/JWTExpiredException.java similarity index 100% rename from java/src/main/java/com/genexus/security/web/jose/jwt/JWTExpiredException.java rename to gxweb/src/main/java/com/genexus/security/web/jose/jwt/JWTExpiredException.java diff --git a/java/src/main/java/com/genexus/security/web/jose/jwt/JWTIssuerException.java b/gxweb/src/main/java/com/genexus/security/web/jose/jwt/JWTIssuerException.java similarity index 100% rename from java/src/main/java/com/genexus/security/web/jose/jwt/JWTIssuerException.java rename to gxweb/src/main/java/com/genexus/security/web/jose/jwt/JWTIssuerException.java diff --git a/java/src/main/java/com/genexus/security/web/jose/jwt/JWTSigner.java b/gxweb/src/main/java/com/genexus/security/web/jose/jwt/JWTSigner.java similarity index 100% rename from java/src/main/java/com/genexus/security/web/jose/jwt/JWTSigner.java rename to gxweb/src/main/java/com/genexus/security/web/jose/jwt/JWTSigner.java diff --git a/java/src/main/java/com/genexus/security/web/jose/jwt/JWTVerifier.java b/gxweb/src/main/java/com/genexus/security/web/jose/jwt/JWTVerifier.java similarity index 100% rename from java/src/main/java/com/genexus/security/web/jose/jwt/JWTVerifier.java rename to gxweb/src/main/java/com/genexus/security/web/jose/jwt/JWTVerifier.java diff --git a/java/src/main/java/com/genexus/security/web/jose/jwt/JWTVerifyException.java b/gxweb/src/main/java/com/genexus/security/web/jose/jwt/JWTVerifyException.java similarity index 100% rename from java/src/main/java/com/genexus/security/web/jose/jwt/JWTVerifyException.java rename to gxweb/src/main/java/com/genexus/security/web/jose/jwt/JWTVerifyException.java diff --git a/java/src/main/java/com/genexus/security/web/jose/jwt/pem/PemFileReader.java b/gxweb/src/main/java/com/genexus/security/web/jose/jwt/pem/PemFileReader.java similarity index 100% rename from java/src/main/java/com/genexus/security/web/jose/jwt/pem/PemFileReader.java rename to gxweb/src/main/java/com/genexus/security/web/jose/jwt/pem/PemFileReader.java diff --git a/java/src/main/java/com/genexus/security/web/jose/jwt/pem/PemFileWriter.java b/gxweb/src/main/java/com/genexus/security/web/jose/jwt/pem/PemFileWriter.java similarity index 100% rename from java/src/main/java/com/genexus/security/web/jose/jwt/pem/PemFileWriter.java rename to gxweb/src/main/java/com/genexus/security/web/jose/jwt/pem/PemFileWriter.java diff --git a/java/src/main/java/com/genexus/security/web/jose/jwt/pem/PemReader.java b/gxweb/src/main/java/com/genexus/security/web/jose/jwt/pem/PemReader.java similarity index 100% rename from java/src/main/java/com/genexus/security/web/jose/jwt/pem/PemReader.java rename to gxweb/src/main/java/com/genexus/security/web/jose/jwt/pem/PemReader.java diff --git a/java/src/main/java/com/genexus/security/web/jose/jwt/pem/PemWriter.java b/gxweb/src/main/java/com/genexus/security/web/jose/jwt/pem/PemWriter.java similarity index 100% rename from java/src/main/java/com/genexus/security/web/jose/jwt/pem/PemWriter.java rename to gxweb/src/main/java/com/genexus/security/web/jose/jwt/pem/PemWriter.java diff --git a/java/src/main/java/com/genexus/security/web/jose/jwt/pem/X509CertUtils.java b/gxweb/src/main/java/com/genexus/security/web/jose/jwt/pem/X509CertUtils.java similarity index 100% rename from java/src/main/java/com/genexus/security/web/jose/jwt/pem/X509CertUtils.java rename to gxweb/src/main/java/com/genexus/security/web/jose/jwt/pem/X509CertUtils.java diff --git a/java/src/main/java/com/genexus/webpanels/DynAjaxEventContext.java b/gxweb/src/main/java/com/genexus/webpanels/DynAjaxEventContext.java similarity index 100% rename from java/src/main/java/com/genexus/webpanels/DynAjaxEventContext.java rename to gxweb/src/main/java/com/genexus/webpanels/DynAjaxEventContext.java diff --git a/gxweb/src/main/java/com/genexus/webpanels/GXMasterPage.java b/gxweb/src/main/java/com/genexus/webpanels/GXMasterPage.java index 6ab3dc59c..000ad05ed 100644 --- a/gxweb/src/main/java/com/genexus/webpanels/GXMasterPage.java +++ b/gxweb/src/main/java/com/genexus/webpanels/GXMasterPage.java @@ -1,6 +1,7 @@ package com.genexus.webpanels; import com.genexus.ModelContext; +import com.genexus.internet.HttpAjaxContext; import com.genexus.internet.HttpContext; public abstract class GXMasterPage extends GXWebPanel @@ -29,14 +30,14 @@ public GXMasterPage(int remoteHandle, ModelContext context) public void setDataArea( GXDataArea DataAreaObject) { this.DataAreaObject = DataAreaObject; - this.httpContext = DataAreaObject.getHttpContext(); + this.httpContext = (HttpAjaxContext) DataAreaObject.getHttpContext(); _ShowMPWhenPopUp = true; } public void setDataArea( GXDataArea DataAreaObject, boolean ShowMPWhenPopUp) { this.DataAreaObject = DataAreaObject; - this.httpContext = DataAreaObject.getHttpContext(); + this.httpContext = (HttpAjaxContext)DataAreaObject.getHttpContext(); _ShowMPWhenPopUp = ShowMPWhenPopUp; } diff --git a/gxweb/src/main/java/com/genexus/webpanels/GXStaticWebPanel.java b/gxweb/src/main/java/com/genexus/webpanels/GXStaticWebPanel.java deleted file mode 100644 index fae699b76..000000000 --- a/gxweb/src/main/java/com/genexus/webpanels/GXStaticWebPanel.java +++ /dev/null @@ -1,155 +0,0 @@ -package com.genexus.webpanels; - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.*; - -import com.genexus.CommonUtil; -import com.genexus.ModelContext; -import com.genexus.PrivateUtilities; -import com.genexus.internet.HttpContext; -import com.genexus.internet.HttpContextNull; - -public abstract class GXStaticWebPanel extends GXWebPanel -{ - private static Hashtable visitedLinks = new Hashtable<>(); - private static Vector copyList = new Vector<>(); - - protected static String extension = "html"; - private String fileName ; - - public static final String STATIC_DIR = "genexus.staticweb.dir"; - public static final String STATIC_DYNURL = "genexus.staticweb.dynurl"; - public static final String STATIC_OVER = "genexus.staticweb.overwrite"; - public static final String STATIC_LINKS = "genexus.staticweb.links"; - public static final String STATIC_COPYDIR = "genexus.staticweb.copydir"; - - private static long startTime = System.currentTimeMillis(); - - HttpContext oldHttpContext; - - public GXStaticWebPanel(HttpContext httpContext) - { - super(httpContext); - } - - public GXStaticWebPanel(int remoteHandle, ModelContext context) - { - super(remoteHandle, context); - oldHttpContext = (HttpContext) context.getHttpContext(); - httpContext = new HttpContextNull(); - - context.setHttpContext(httpContext); - httpContext.setBuffered(false); - } - - protected void createFile(String fileName) - { - try - { - visitedLinks.put(fileName, ""); - ((HttpContext) context.getHttpContext()).setOutputStream(new BufferedOutputStream(new FileOutputStream(fileName))); - - addMessage("Creating " + fileName + "..."); - - this.fileName = fileName; - } - catch (IOException e) - { - throw new RuntimeException(e.getMessage()); - } - } - - public static byte copyFiles() - { - String outputDir = PrivateUtilities.addLastPathSeparator(PrivateUtilities.getSystemProperty(STATIC_COPYDIR, "")); - - if (!outputDir.trim().equals("")) - { - for (Enumeration en = copyList.elements(); en.hasMoreElements(); ) - { - String fileName = (String) en.nextElement(); - System.out.println("Copying " + getStaticDir() + fileName + " to " + outputDir + fileName); - PrivateUtilities.copyFileRetry(getStaticDir() + fileName, outputDir + fileName); - } - } - - visitedLinks = new Hashtable<>(); - - copyList.removeAllElements(); - return 0; - } - - protected void addFileToCopy(String file) - { - if (!PrivateUtilities.getSystemProperty(STATIC_COPYDIR, "").equals("")) - copyList.addElement(file); - } - - protected int processParameters(String args[]) - { - return 0; - } - - public static byte isStaticOverwrite() - { - return PrivateUtilities.getSystemProperty(STATIC_OVER, "true").equals("true")?(byte) 1:0; - } - - public static byte isExpandLinks() - { - return PrivateUtilities.getSystemProperty(STATIC_LINKS, "true").equals("true")?(byte) 1:0; - } - - public static byte isStaticCreated(String link) - { - return visitedLinks.get(link) == null? (byte) 0 :(byte) 1; - } - - protected byte wasVisited(String link) - { - if ( (PrivateUtilities.getSystemProperty(STATIC_OVER, "true").equals("false") && new File(getStaticDir() + link).exists()) || - (PrivateUtilities.getSystemProperty(STATIC_LINKS, "true").equals("false")) ) - { - return 1; - } - - return visitedLinks.get(link) == null? 0 :(byte) 1; - } - - protected static String getTime() - { - Date d = new Date(); - Calendar calendar = GregorianCalendar.getInstance(); - calendar.setTime(d); - return CommonUtil.padl(""+ calendar.get(Calendar.HOUR_OF_DAY), 2, "0") + ":" + - CommonUtil.padl(""+ calendar.get(Calendar.MINUTE), 2, "0") + ":" + - CommonUtil.padl(""+ calendar.get(Calendar.SECOND), 2, "0"); - } - - protected String encodeStaticParm(String parm) - { - return CommonUtil.URLEncode(parm, "UTF8"); - } - - public static String getStaticDir() - { - return PrivateUtilities.addLastPathSeparator(WebUtils.getSystemProperty(STATIC_DIR)); - } - - private void addMessage(String msg) - { - System.out.println(msg); - } - - protected void cleanup() - { - if (isStaticGeneration) - addMessage("Closing " + fileName + "..."); - - super.cleanup(); - context.setHttpContext(oldHttpContext); - } -} \ No newline at end of file diff --git a/gxweb/src/main/java/com/genexus/webpanels/GXUserControl.java b/gxweb/src/main/java/com/genexus/webpanels/GXUserControl.java index 9ae3ff866..78cacdf48 100644 --- a/gxweb/src/main/java/com/genexus/webpanels/GXUserControl.java +++ b/gxweb/src/main/java/com/genexus/webpanels/GXUserControl.java @@ -1,6 +1,7 @@ package com.genexus.webpanels; + import com.genexus.ModelContext; -import com.genexus.internet.HttpContext; +import com.genexus.internet.HttpAjaxContext; import com.genexus.usercontrols.UserControlFactoryImpl; import com.genexus.util.GXMap; @@ -32,13 +33,13 @@ public void setProperty(String propertyName, Object propertyValue) } public void sendProperty(ModelContext context, String componentPrefix, boolean isMasterPage, String internalName, String propertyName, String propertyValue) { - ((HttpContext)context.getHttpContext()).ajax_rsp_assign_uc_prop(componentPrefix, isMasterPage, internalName, propertyName, propertyValue); + ((HttpAjaxContext)context.getHttpContext()).ajax_rsp_assign_uc_prop(componentPrefix, isMasterPage, internalName, propertyName, propertyValue); setProperty(propertyName, propertyValue); } public void render(ModelContext context, String controlType, String internalName, String htmlId) { propertyBag.put("ContainerName", htmlId); String ucServerContent = UserControlFactoryImpl.getInstance().renderControl(controlType, internalName, propertyBag); - ((HttpContext)context.getHttpContext()).writeText( String.format("
%s
", htmlId, ucServerContent)); + ((HttpAjaxContext)context.getHttpContext()).writeText( String.format("
%s
", htmlId, ucServerContent)); } } diff --git a/gxweb/src/main/java/com/genexus/webpanels/GXWebGrid.java b/gxweb/src/main/java/com/genexus/webpanels/GXWebGrid.java index f7d3fc7a2..45c32ec30 100644 --- a/gxweb/src/main/java/com/genexus/webpanels/GXWebGrid.java +++ b/gxweb/src/main/java/com/genexus/webpanels/GXWebGrid.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import com.genexus.ModelContext; +import com.genexus.internet.HttpAjaxContext; import com.genexus.internet.HttpContext; import com.genexus.internet.IGxJSONAble; import com.genexus.common.interfaces.IGXWebGrid; @@ -62,7 +63,7 @@ public void setWritingTableContent(boolean writingTableContent) public void SetWrapped(int wrapped) { - HttpContext httpContext = (HttpContext) this.context.getHttpContext(); + HttpAjaxContext httpContext = (HttpAjaxContext) context.getHttpContext(); this.wrapped = (wrapped==1); if (!this.wrapped) { diff --git a/gxweb/src/main/java/com/genexus/webpanels/GXWebObjectBase.java b/gxweb/src/main/java/com/genexus/webpanels/GXWebObjectBase.java new file mode 100644 index 000000000..c65510e6a --- /dev/null +++ b/gxweb/src/main/java/com/genexus/webpanels/GXWebObjectBase.java @@ -0,0 +1,265 @@ +package com.genexus.webpanels; + +import org.apache.commons.lang.StringUtils; + +import com.genexus.*; +import com.genexus.configuration.ConfigurationManager; +import com.genexus.diagnostics.core.ILogger; +import com.genexus.diagnostics.core.LogManager; +import com.genexus.diagnostics.GXDebugInfo; +import com.genexus.diagnostics.GXDebugManager; +import com.genexus.internet.HttpAjaxContext; +import com.genexus.internet.GXInternetConstants; +import com.genexus.internet.HttpContext; +import com.genexus.ModelContext; +import com.genexus.security.GXSecurityProvider; + +public abstract class GXWebObjectBase extends GXObjectBase implements IErrorHandler, GXInternetConstants +{ + public static final ILogger logger = LogManager.getLogger(GXWebObjectBase.class); + + private static String GX_SPA_GXOBJECT_RESPONSE_HEADER = "X-GXOBJECT"; + protected static String GX_SPA_MASTERPAGE_HEADER = "X-SPA-MP"; + protected static String GX_AJAX_MULTIPART_ID = "GXAjaxMultipart"; + + protected boolean IntegratedSecurityEnabled() { return false;} + protected int IntegratedSecurityLevel() { return 0;} + protected String IntegratedSecurityPermissionPrefix() {return "";} + + protected HttpAjaxContext httpContext; + + public abstract void webExecute(); + public abstract boolean isMasterPage(); + + public GXWebObjectBase() + { + } + + /** + * Este constructor se usa cuando aun no tengo un ModelContext ni remoteHandle, pero + * si tengo el HttpContext. Basicamente es el punto de entrada en los servlets. + */ + public GXWebObjectBase(HttpContext httpContext, Class contextClass) + { + init(httpContext, contextClass); + castHttpContext(); + } + + /** + * Este constructor se usa cuando aun no tengo un ModelContext ni remoteHandle, pero + * si tengo el HttpContext. Basicamente es el punto de entrada en los servlets. + */ + public GXWebObjectBase(HttpContext httpContext) + { + super(httpContext); + castHttpContext(); + } + + /** + * Este constructor se usa cuando ya tengo un ModelContext y remoteHandle. + * Basicamente es el punto de entrada para webcomponents, webwrappers, etc. + */ + public GXWebObjectBase(int remoteHandle, ModelContext context) + { + super(remoteHandle, context); + castHttpContext(); + } + + private void castHttpContext() { + this.httpContext = (HttpAjaxContext) super.httpContext; + } + /*** + * Return the DefaultTheme for all WebPanels and Transactions. + * @return + */ + @SuppressWarnings("unused") + protected void initializeTheme() { + this.httpContext.setDefaultTheme(ConfigurationManager.getValue("Theme")); + } + + protected boolean CheckCmpSecurityAccess() + { + boolean[] flag = new boolean[]{false}; + boolean[] permissionFlag = new boolean[]{false}; + String permissionPrefix = IntegratedSecurityPermissionPrefix(); + com.genexus.internet.HttpRequest req = ((HttpContext)ModelContext.getModelContext().getHttpContext()).getHttpRequest(); + if (req == null) + return false; + String reqUrl = req.getRequestURL(); + ModelContext modelContext = ModelContext.getModelContext(getClass()); + if (IntegratedSecurityLevel() == SECURITY_LOW || IntegratedSecurityLevel() == SECURITY_GXOBJECT) + { + GXSecurityProvider.getInstance().checksession(-2, modelContext, reqUrl, permissionFlag); + } + if (IntegratedSecurityLevel() != SECURITY_LOW && IntegratedSecurityLevel() != SECURITY_GXOBJECT) + { + GXSecurityProvider.getInstance().checksessionprm(-2, modelContext, reqUrl, permissionPrefix, flag, permissionFlag); + } + return permissionFlag[0]; + } + + protected void sendCacheHeaders() + { + if (httpContext.isSpaRequest()) { + httpContext.getResponse().setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); + httpContext.getResponse().setHeader("Pragma", "no-cache"); + httpContext.getResponse().setHeader("Expires", "0"); + } + else { + super.sendCacheHeaders(); + } + } + + protected void sendAdditionalHeaders() + { + if (httpContext.isSpaRequest()) + sendSpaHeaders(); + if (httpContext.getBrowserType() == HttpContextWeb.BROWSER_IE && !httpContext.isPopUpObject()) + { + String IECompMode = context.getClientPreferences().getIE_COMPATIBILITY(); + if (IECompMode.equals("EmulateIE7") && !httpContext.getBrowserVersion().startsWith("8") ) + return; + if (StringUtils.isNotEmpty(IECompMode)) + httpContext.getResponse().addHeader("X-UA-Compatible", "IE=" + IECompMode); + } + } + + protected void sendSpaHeaders() + { + httpContext.getResponse().setHeader(GX_SPA_GXOBJECT_RESPONSE_HEADER, getPgmname().toLowerCase()); + } + + public void doExecute() throws Exception + { + try + { + if (isSpaRequest() && !isSpaSupported()) + { + httpContext.sendResponseStatus(httpContext.SPA_NOT_SUPPORTED_STATUS_CODE, "SPA not supported by the object"); + } + else + { + preExecute(); + sendCacheHeaders(); + webExecute(); + sendAdditionalHeaders(); + httpContext.flushStream(); + } + } + catch (Throwable e) + { + cleanup(); // Antes de hacer el rethrow, hago un cleanup del objeto + throw e; + } + finally + { + finallyCleanup(); + } + } + + public void executeUsercontrolMethod(String CmpContext, boolean IsMasterPage, String containerName, String methodName, String input, Object[] parms) + { + httpContext.executeUsercontrolMethod(CmpContext, IsMasterPage, containerName, methodName, input, parms); + } + + public void setExternalObjectProperty(String CmpContext, boolean IsMasterPage, String containerName, String propertyName, Object value) + { + httpContext.setExternalObjectProperty(CmpContext, IsMasterPage, containerName, propertyName, value); + } + + public void executeExternalObjectMethod(String CmpContext, boolean IsMasterPage, String containerName, String methodName, Object[] parms, boolean isEvent) + { + httpContext.executeExternalObjectMethod(CmpContext, IsMasterPage, containerName, methodName, parms, isEvent); + } + + public String getPgmname() + { + return ""; + } + + public String getPgmdesc() + { + return ""; + } + + protected boolean isSpaRequest() + { + return httpContext.isSpaRequest(); + } + + protected boolean isSpaRequest(boolean ignoreFlag) + { + return httpContext.isSpaRequest(ignoreFlag); + } + + protected boolean isSpaSupported() + { + return true; + } + + + protected void validateSpaRequest() + { + // SPA is disabled for objects without master page. However, SPA response headers are sent anyway, so the client side + // replaces the full content using AJAX. + if (isSpaRequest()) + { + httpContext.disableSpaRequest(); + sendSpaHeaders(); + } + } + + protected String getPgmInstanceId(String cmpCtx) + { + return String.format("%s%s", cmpCtx, this.getPgmname().toUpperCase()); + } + + private GXDebugInfo dbgInfo = null; + protected void trkCleanup() + { + if(dbgInfo != null) + dbgInfo.onCleanup(); + } + + protected void initialize(int objClass, int objId, int dbgLines, long hash) + { + dbgInfo = GXDebugManager.getInstance().getDbgInfo(context, objClass, objId, dbgLines, hash); + } + + protected void trk(int lineNro) + { + if(dbgInfo != null) + dbgInfo.trk(lineNro); + } + + protected void trk(int lineNro, int lineNro2) + { + if(dbgInfo != null) + dbgInfo.trk(lineNro, lineNro2); + } + + protected void trkrng(int lineNro, int lineNro2) + { + trkrng(lineNro, 0, lineNro2, 0); + } + + protected void trkrng(int lineNro, int colNro, int lineNro2, int colNro2) + { + if(dbgInfo != null) + dbgInfo.trkRng(lineNro, colNro, lineNro2, colNro2); + } + + protected void callWebObject(String url) + { + httpContext.wjLoc = url; + } + + + public void popup(String url) + { + } + + public void popup(String url, Object[] returnParms) + { + } +} diff --git a/gxweb/src/main/java/com/genexus/webpanels/GXWebPanel.java b/gxweb/src/main/java/com/genexus/webpanels/GXWebPanel.java index 8fa09a8ad..5a1799ab0 100644 --- a/gxweb/src/main/java/com/genexus/webpanels/GXWebPanel.java +++ b/gxweb/src/main/java/com/genexus/webpanels/GXWebPanel.java @@ -4,6 +4,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.lang.reflect.*; +import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.ArrayList; @@ -15,14 +16,18 @@ import com.genexus.db.UserInformation; import com.genexus.diagnostics.core.ILogger; import com.genexus.diagnostics.core.LogManager; +import com.genexus.internet.HttpAjaxContext; import com.genexus.internet.HttpContext; import com.genexus.internet.IGxJSONSerializable; import com.genexus.security.GXSecurityProvider; +import com.genexus.security.web.SecureTokenHelper; +import com.genexus.security.web.WebSecurityHelper; import json.org.json.IJsonFormattable; import json.org.json.JSONArray; import json.org.json.JSONException; import json.org.json.JSONObject; +import org.apache.commons.lang.StringUtils; class DataIntegrityException extends Exception { @@ -214,6 +219,7 @@ protected void setEventMetadata(String eventName, String metadata) { protected void initState(ModelContext context, UserInformation ui) { super.initState(context, ui); + httpContext = (HttpAjaxContext) context.getHttpContext(); staticDir = context.getClientPreferences().getWEB_STATIC_DIR(); @@ -433,7 +439,7 @@ public void doExecute() throws Exception { if (isSpaRequest() && !isSpaSupported()) { - httpContext.sendResponseStatus(SPA_NOT_SUPPORTED_STATUS_CODE, "SPA not supported by the object"); + httpContext.sendResponseStatus(HttpContext.SPA_NOT_SUPPORTED_STATUS_CODE, "SPA not supported by the object"); } else { @@ -446,7 +452,6 @@ public void doExecute() throws Exception } catch (Throwable e) { - handleException(e.getClass().getName(), e.getMessage(), CommonUtil.getStackTraceAsString(e)); cleanup(); // Antes de hacer el rethrow, hago un cleanup del objeto throw e; } @@ -475,13 +480,13 @@ public void webAjaxEvent() throws Exception { else httpContext.setContentType("application/json"); - if (!redirect((HttpContextWeb) httpContext)){ - ((HttpContextWeb)httpContext).sendFinalJSONResponse(jsonResponse); + if (!redirect(httpContext)){ + httpContext.sendFinalJSONResponse(jsonResponse); } httpContext.setResponseCommited(); } - private boolean redirect(HttpContextWeb context) + private boolean redirect(HttpAjaxContext context) { if (context.wjLoc!=null && !context.wjLoc.equals("") ) { @@ -1214,4 +1219,223 @@ public void newWindow(IGXWindow win) { WebFrontendUtils.newWindow(win, httpContext); } + protected String getSecureSignedToken(String cmpCtx, Object Value) + { + return getSecureSignedToken(cmpCtx, serialize(Value)); + } + + protected String getSecureSignedToken(String cmpCtx, boolean Value) + { + return getSecureSignedToken(cmpCtx, Boolean.toString(Value)); + } + + protected String getSecureSignedToken(String cmpCtx, com.genexus.xml.GXXMLSerializable Value) + { + return getSecureSignedToken(cmpCtx, Value.toJSonString(false)); + } + + protected String getSecureSignedToken(String cmpCtx, String Value) + { + return WebSecurityHelper.sign(getPgmInstanceId(cmpCtx), "", Value, SecureTokenHelper.SecurityMode.Sign, getSecretKey()); + } + + protected boolean verifySecureSignedToken(String cmpCtx, int Value, String picture, String token){ + return verifySecureSignedToken(cmpCtx, serialize(Value, picture), token); + } + + protected boolean verifySecureSignedToken(String cmpCtx, short Value, String picture, String token){ + return verifySecureSignedToken(cmpCtx, serialize(Value, picture), token); + } + + protected boolean verifySecureSignedToken(String cmpCtx, long Value, String picture, String token){ + return verifySecureSignedToken(cmpCtx, serialize(Value, picture), token); + } + + protected boolean verifySecureSignedToken(String cmpCtx, double Value, String picture, String token){ + return verifySecureSignedToken(cmpCtx, serialize(Value, picture), token); + } + + protected boolean verifySecureSignedToken(String cmpCtx, Object Value, String picture, String token){ + return verifySecureSignedToken(cmpCtx, serialize(Value, picture), token); + } + + protected boolean verifySecureSignedToken(String cmpCtx, Object Value, String token){ + return verifySecureSignedToken(cmpCtx, serialize(Value), token); + } + + protected boolean verifySecureSignedToken(String cmpCtx, boolean Value, String token){ + return verifySecureSignedToken(cmpCtx, Boolean.toString(Value), token); + } + + protected boolean verifySecureSignedToken(String cmpCtx, com.genexus.xml.GXXMLSerializable Value, String token){ + return verifySecureSignedToken(cmpCtx, Value.toJSonString(false), token); + } + + protected boolean verifySecureSignedToken(String cmpCtx, String value, String token){ + return WebSecurityHelper.verify(getPgmInstanceId(cmpCtx), "", value, token, getSecretKey()); + } + + protected boolean validateObjectAccess(String cmpCtx) + { + if (this.httpContext.useSecurityTokenValidation()){ + String jwtToken = this.httpContext.getHeader("X-GXAUTH-TOKEN"); + jwtToken = (StringUtils.isBlank(jwtToken) && this.httpContext.isMultipartContent())? + this.httpContext.cgiGet("X-GXAUTH-TOKEN"): + jwtToken; + + if (!verifySecureSignedToken(cmpCtx, "", jwtToken)) + { + this.httpContext.sendResponseStatus(401, "Not Authorized"); + if (this.httpContext.getBrowserType() != HttpContextWeb.BROWSER_INDEXBOT) { + logger.warn(String.format("Validation security token failed for program: %s - '%s'", getPgmInstanceId(cmpCtx), jwtToken )); + } + return false; + } + } + return true; + } + + private static String GX_SEC_TOKEN_PREFIX = "GX_AUTH"; + + //Generates only with FullAjax and GAM disabled. + public void sendSecurityToken(String cmpCtx) + { + if (this.httpContext.wjLoc == null || this.httpContext.wjLoc.equals("") ) + { + this.httpContext.ajax_rsp_assign_hidden(getSecurityObjTokenId(cmpCtx), getObjectAccessWebToken(cmpCtx)); + } + } + + private String getSecurityObjTokenId(String cmpCtx) + { + return GX_SEC_TOKEN_PREFIX + "_" + cmpCtx + getPgmname().toUpperCase(); + } + + private String getObjectAccessWebToken(String cmpCtx) + { + return WebSecurityHelper.sign(getPgmInstanceId(cmpCtx), "", "", SecureTokenHelper.SecurityMode.Sign, getSecretKey()); + } + + private String getSecretKey() + { + //Some random SALT that is different in every GX App installation. Better if changes over time + String hashSalt = com.genexus.Application.getClientContext().getClientPreferences().getREORG_TIME_STAMP(); + return WebUtils.getEncryptionKey(this.context, "") + hashSalt; + } + + private String serialize(double Value, String Pic) + { + return serialize(localUtil.format(Value, Pic)); + } + + private String serialize(int Value, String Pic) + { + return serialize(localUtil.format(Value, Pic)); + } + + private String serialize(short Value, String Pic) + { + return serialize(localUtil.format(Value, Pic)); + } + + private String serialize(long Value, String Pic) + { + return serialize(localUtil.format(Value, Pic)); + } + + private String serialize(Object Value, String Pic) + { + if (!StringUtils.isBlank(Pic)) { + if (Value instanceof Byte) + { + return serialize(localUtil.format(((Byte)Value).intValue(), Pic)); + } + else + { + if (Value instanceof BigDecimal) + { + return serialize(localUtil.format((BigDecimal)Value, Pic)); + } + else + { + if (Value instanceof Integer) + { + return serialize(localUtil.format(((Integer)Value).intValue(), Pic)); + } + else + { + if (Value instanceof Short) + { + return serialize(localUtil.format(((Short)Value).shortValue(), Pic)); + } + else + { + if (Value instanceof Long) + { + return serialize(localUtil.format(((Long)Value).longValue(), Pic)); + } + else + { + if (Value instanceof Double) + { + return serialize(localUtil.format(((Double)Value).doubleValue(), Pic)); + } + else + { + if (Value instanceof Float) + { + return serialize(localUtil.format(((Float)Value).floatValue(), Pic)); + } + else + { + if (Value instanceof java.util.Date) + { + return serialize(localUtil.format((java.util.Date)Value, Pic)); + } + else + { + if (Value instanceof String) + { + return serialize(localUtil.format((String)Value, Pic)); + } + } + } + } + } + } + } + } + } + } + return serialize(Value); + } + + private String serialize(Object Value) { + String strValue = ""; + if (Value instanceof BigDecimal){ + strValue = Value.toString(); + if (strValue.indexOf(".") != -1) + strValue = strValue.replaceAll("0*$", "").replaceAll("\\.$", ""); + } + else{ + if (Value instanceof java.util.Date){ + strValue = " / / 00:00:00"; + if (!Value.equals(CommonUtil.resetTime( CommonUtil.nullDate()))) { + strValue = new java.text.SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(Value); + } + } + else{ + if (Value instanceof com.genexus.xml.GXXMLSerializable) { + strValue = ((com.genexus.xml.GXXMLSerializable) Value).toJSonString(false); + } + else if (Value instanceof IGxJSONSerializable) { + strValue = ((IGxJSONSerializable) Value).toJSonString(); + } + else { + strValue = Value.toString(); + } + } + } + return strValue; + } } diff --git a/gxweb/src/main/java/com/genexus/webpanels/GXWebPanelStub.java b/gxweb/src/main/java/com/genexus/webpanels/GXWebPanelStub.java new file mode 100644 index 000000000..d2c28140d --- /dev/null +++ b/gxweb/src/main/java/com/genexus/webpanels/GXWebPanelStub.java @@ -0,0 +1,33 @@ +package com.genexus.webpanels; + +import com.genexus.ModelContext; +import com.genexus.internet.HttpAjaxContext; +import com.genexus.internet.HttpContext; +import com.genexus.servlet.ServletException; +import com.genexus.servlet.http.IHttpServletRequest; +import com.genexus.servlet.http.IHttpServletResponse; + +public abstract class GXWebPanelStub extends GXWebObjectStub{ + + public GXWebPanelStub() + { + } + + public GXWebPanelStub(int remoteHandle , ModelContext context) + { + super(remoteHandle, context); + } + + protected void callExecute(String method, IHttpServletRequest req, IHttpServletResponse res) throws ServletException { + HttpContext httpContext = null; + try + { + httpContext = new HttpAjaxContext(method, req, res, getWrappedServletContext()); + super.callExecute(method, req, res, httpContext); + } + catch (Exception e) + { + handleException(e, httpContext); + } + } +} diff --git a/gxweb/src/main/java/com/genexus/webpanels/GXWebRow.java b/gxweb/src/main/java/com/genexus/webpanels/GXWebRow.java index cc2ac580a..a53e39974 100644 --- a/gxweb/src/main/java/com/genexus/webpanels/GXWebRow.java +++ b/gxweb/src/main/java/com/genexus/webpanels/GXWebRow.java @@ -4,6 +4,7 @@ import com.genexus.CommonUtil; import com.genexus.ModelContext; +import com.genexus.internet.HttpAjaxContext; import com.genexus.internet.HttpContext; import com.genexus.internet.IGxJSONAble; import com.genexus.common.interfaces.IGXWebRow; @@ -80,9 +81,9 @@ public void AddColumnProperties(String controlType, int valueIndex, boolean valu this.firstRowAdded = true; return; } - ((HttpContext)context.getHttpContext()).drawingGrid = true; + ((HttpAjaxContext)context.getHttpContext()).drawingGrid = true; GXWebStdMethods.callMethod(this.context, controlType, props, _parentGrid.getGridName()); - ((HttpContext)context.getHttpContext()).drawingGrid = false; + ((HttpAjaxContext)context.getHttpContext()).drawingGrid = false; if (!this._parentGrid.isFreestyle()) { GXWebStdMethods.closeTag(this.context, "cell"); diff --git a/gxweb/src/main/java/com/genexus/webpanels/GXWebStdMethods.java b/gxweb/src/main/java/com/genexus/webpanels/GXWebStdMethods.java index 36756ed9c..b5bbe9755 100644 --- a/gxweb/src/main/java/com/genexus/webpanels/GXWebStdMethods.java +++ b/gxweb/src/main/java/com/genexus/webpanels/GXWebStdMethods.java @@ -3,7 +3,7 @@ import java.lang.reflect.Method; import com.genexus.ModelContext; -import com.genexus.internet.HttpContext; +import com.genexus.internet.HttpAjaxContext; public class GXWebStdMethods { @@ -67,7 +67,7 @@ public static void callMethod(ModelContext context, String controlType, Object[] Class webStdFuncs = getWebStdClass(context); if (webStdFuncs != null) { - HttpContext httpContext = (HttpContext) context.getHttpContext(); + HttpAjaxContext httpContext = (HttpAjaxContext) context.getHttpContext(); if (httpContext != null) { boolean addCallerPgm = true; @@ -202,7 +202,7 @@ private static boolean tagHasStdMethod(String tag) public static void openTag(ModelContext context, String tag, Object[] parms) { - HttpContext httpContext = (HttpContext) context.getHttpContext(); + HttpAjaxContext httpContext = (HttpAjaxContext) context.getHttpContext(); if (tag.equalsIgnoreCase("row")) { httpContext.writeTextNL(""); @@ -230,7 +230,7 @@ else if (tag.equalsIgnoreCase("usercontrol")) public static void closeTag(ModelContext context, String tag) { - HttpContext httpContext = (HttpContext) context.getHttpContext(); + HttpAjaxContext httpContext = (HttpAjaxContext) context.getHttpContext(); if (tag.equalsIgnoreCase("table")) { httpContext.writeTextNL(""); diff --git a/java/src/main/java/com/genexus/webpanels/IDynAjaxEventContext.java b/gxweb/src/main/java/com/genexus/webpanels/IDynAjaxEventContext.java similarity index 100% rename from java/src/main/java/com/genexus/webpanels/IDynAjaxEventContext.java rename to gxweb/src/main/java/com/genexus/webpanels/IDynAjaxEventContext.java diff --git a/gxweb/src/main/java/com/genexus/webpanels/NoneMasterPage.java b/gxweb/src/main/java/com/genexus/webpanels/NoneMasterPage.java index f38de0ec2..88fc1aa3d 100644 --- a/gxweb/src/main/java/com/genexus/webpanels/NoneMasterPage.java +++ b/gxweb/src/main/java/com/genexus/webpanels/NoneMasterPage.java @@ -1,15 +1,7 @@ -/* - File: nonemasterpage_impl - Description: None Master Page - Author: GeneXus Java Generator version 15_0_12-126415 - Generated on: April 26, 2019 17:13:47.18 - Program type: Callable routine - Main DBMS: SQL Server -*/ package com.genexus.webpanels; + import com.genexus.*; -import com.genexus.internet.HttpContext; -import com.genexus.webpanels.*; +import com.genexus.internet.HttpAjaxContext; public final class NoneMasterPage extends GXMasterPage { @@ -206,7 +198,7 @@ public void wb0A0( ) wbLoad = true ; } - public static void classAttribute( HttpContext httpContext , + public static void classAttribute( HttpAjaxContext httpContext , String sClass ) { if ( ! (GXutil.strcmp("", sClass)==0) ) @@ -218,7 +210,7 @@ public static void classAttribute( HttpContext httpContext , } - public static void gx_div_start( HttpContext httpContext , + public static void gx_div_start( HttpAjaxContext httpContext , String sInternalName , int nVisible , int nWidth , @@ -284,7 +276,7 @@ public static void gx_div_start( HttpContext httpContext , } } - public static void styleAttribute( HttpContext httpContext , + public static void styleAttribute( HttpAjaxContext httpContext , String sStyle ) { if ( ! (GXutil.strcmp("", sStyle)==0) ) @@ -295,7 +287,7 @@ public static void styleAttribute( HttpContext httpContext , } } - public static void gx_div_end( HttpContext httpContext , + public static void gx_div_end( HttpAjaxContext httpContext , String sAlign , String sVAlign , String sHtmlTag ) @@ -311,7 +303,7 @@ public static void gx_div_end( HttpContext httpContext , httpContext.writeText( "") ; } - public static boolean gx_redirect( HttpContext httpContext ) + public static boolean gx_redirect( HttpAjaxContext httpContext ) { if ( httpContext.willRedirect( ) ) { diff --git a/gxweb/src/main/java/com/genexus/webpanels/WebFrontendUtils.java b/gxweb/src/main/java/com/genexus/webpanels/WebFrontendUtils.java index e76f0b4b2..7e0ce40f4 100644 --- a/gxweb/src/main/java/com/genexus/webpanels/WebFrontendUtils.java +++ b/gxweb/src/main/java/com/genexus/webpanels/WebFrontendUtils.java @@ -2,7 +2,10 @@ import com.genexus.*; import com.genexus.common.interfaces.IGXWindow; +import com.genexus.internet.HttpAjaxContext; import com.genexus.internet.HttpContext; +import com.genexus.reports.GXReport; +import com.genexus.reports.GXReportText; public class WebFrontendUtils { @@ -65,4 +68,14 @@ public static void newWindow(IGXWindow win, HttpContext httpContext) { ((HttpContextWeb) httpContext).redirect_impl(win.getUrl(), win); } + public static void printReportAtClient(GXProcedure reportClass, HttpContext httpContext, String printerRule) { + String fileName; + if (reportClass instanceof GXReport) + fileName = ((GXReport)reportClass).setPrintAtClient(); + else + fileName = ((GXReportText)reportClass).setPrintAtClient(); + if (httpContext != null) + ((HttpAjaxContext) httpContext).printReportAtClient(fileName, printerRule); + } + } \ No newline at end of file diff --git a/java/src/main/java/com/genexus/GXObjectBase.java b/java/src/main/java/com/genexus/GXObjectBase.java new file mode 100644 index 000000000..f30f5ca15 --- /dev/null +++ b/java/src/main/java/com/genexus/GXObjectBase.java @@ -0,0 +1,227 @@ +package com.genexus; + +import com.genexus.db.Namespace; +import com.genexus.db.UserInformation; +import com.genexus.diagnostics.core.ILogger; +import com.genexus.diagnostics.core.LogManager; +import com.genexus.internet.HttpContext; +import com.genexus.webpanels.HttpContextWeb; +import com.genexus.webpanels.WebApplicationStartup; + +import java.sql.SQLException; + +public abstract class GXObjectBase extends GXRestServiceWrapper implements ISubmitteable{ + public static final ILogger logger = LogManager.getLogger(GXObjectBase.class); + + protected ModelContext context; + protected HttpContext httpContext; + protected LocalUtil localUtil; + protected int remoteHandle = -1; + protected UserInformation ui; + + protected static final int SECURITY_GXOBJECT = 3; + protected static final int SECURITY_HIGH = 2; + protected static final int SECURITY_LOW = 1; + + public abstract void webExecute(); + + public GXObjectBase() { + } + + /** + * Este constructor se usa cuando aun no tengo un ModelContext ni remoteHandle, pero + * si tengo el HttpContext. Basicamente es el punto de entrada en los servlets. + */ + public GXObjectBase(HttpContext httpContext) { + init(httpContext, getClass()); + } + + /** + * Este constructor se usa cuando ya tengo un ModelContext y remoteHandle. + * Basicamente es el punto de entrada para webcomponents, webwrappers, etc. + */ + public GXObjectBase(int remoteHandle, ModelContext context) { + this.context = context; + + ui = (UserInformation) GXObjectHelper.getUserInformation(context, remoteHandle); + this.remoteHandle = ui.getHandle(); + + initState(context, ui); + } + + protected void init(HttpContext httpContext, Class contextClass) { + this.context = new ModelContext(contextClass); + context.setHttpContext(httpContext); + + new WebApplicationStartup().init(contextClass, httpContext); + + ApplicationContext.getInstance().setPoolConnections(!Namespace.createNamespace(context).isRemoteGXDB()); + + ui = (UserInformation) GXObjectHelper.getUserInformation(context, -1); + ui.setAutoDisconnect(false); + remoteHandle = ui.getHandle(); + + initState(context, ui); + } + + protected void initState(ModelContext context, UserInformation ui) { + localUtil = ui.getLocalUtil(); + httpContext = (HttpContext) context.getHttpContext(); + httpContext.setContext( context); + httpContext.setCompression(getCompressionMode()); + } + + protected boolean getCompressionMode() { + return context.getClientPreferences().getCOMPRESS_HTML(); + } + + public int setLanguage(String language) { + int res = GXutil.setLanguage(language, context, ui); + localUtil = ui.getLocalUtil(); + return res; + } + + public int setTheme(String theme) { + int res = GXutil.setTheme(theme, context); + return res; + } + + public void doExecute() throws Exception + { + try + { + preExecute(); + sendCacheHeaders(); + webExecute(); + httpContext.flushStream(); + } + catch (Throwable e) + { + cleanup(); + throw e; + } + finally + { + finallyCleanup(); + } + } + + protected void preExecute() + { + httpContext.responseContentType("text/html"); //default Content-Type + httpContext.initClientId(); + } + + protected void sendCacheHeaders() + { + httpContext.getResponse().addDateHeader("Expires", 0); + httpContext.getResponse().addDateHeader("Last-Modified", 0); + if (this instanceof GXWebReport && ((GXWebReport)this).getOutputType()==GXWebReport.OUTPUT_PDF) { + httpContext.getResponse().addHeader("Cache-Control", "must-revalidate,post-check=0, pre-check=0"); + //Estos headers se setean por un bug de Reader X que hace que en IE no se vea el reporte cuando esta embebido, + //solo se ve luego de hacer F5. + } + else { + httpContext.getResponse().addHeader("Cache-Control", "max-age=0, no-cache, no-store, must-revalidate"); + } + } + + protected void finallyCleanup() { + try { + if (ui!= null) + ui.disconnect(); + } + catch (java.sql.SQLException e) { + logger.error("Exception while disconecting ", e); + } + if (httpContext != null) + httpContext.cleanup(); + cleanModelContext(); + } + + private void cleanModelContext() { + try { + ((ThreadLocal)com.genexus.CommonUtil.threadCalendar).getClass().getMethod("remove", new Class[0]).invoke(com.genexus.CommonUtil.threadCalendar, (java.lang.Object[])new Class[0]); + ((ThreadLocal)com.genexus.ModelContext.threadModelContext).getClass().getMethod("remove", new Class[0]).invoke(com.genexus.ModelContext.threadModelContext, (java.lang.Object[])new Class[0]); + } + catch (NoSuchMethodException e) { + logger.error("cleanModelContext", e); + } + catch (IllegalAccessException e) { + logger.error("cleanModelContext", e); + } + catch (java.lang.reflect.InvocationTargetException e) { + logger.error("cleanModelContext " + e.getTargetException(), e); + } + } + + protected void cleanup() { + Application.cleanupConnection(remoteHandle); + } + + public HttpContext getHttpContext() { + return httpContext; + } + + public void setHttpContext(HttpContext httpContext) { + this.httpContext = (HttpContextWeb) httpContext; + } + + public ModelContext getModelContext() { + return context; + } + + public int getRemoteHandle() { + return remoteHandle; + } + + public ModelContext getContext() { + return context; + } + + public void handleError() { + new DefaultErrorHandler().handleError(context, remoteHandle); + } + + public Object getParm( Object[] parms, int index) + { + return parms[index]; + } + + protected String formatLink(String jumpURL) + { + return formatLink(jumpURL, new String[]{}); + } + + protected String formatLink(String jumpURL, String[] parms) + { + return formatLink(jumpURL, parms, new String[]{}); + } + + protected String formatLink(String jumpURL, String[] parms, String[] parmsName) + { + return URLRouter.getURLRoute(jumpURL, parms, parmsName, httpContext.getRequest().getContextPath(), context.getPackageName()); + } + + /** + * @Hack: Tenemos que ejecutar el submit esto en otro thread, pues el submit es asincrono, + * pero si creamos en el fuente generado el codigo del nuevo thread, se va a crear un + * archivo nuevo xxx$N.class al compilar el xxx, que deberia ser tratado especialmente + * en el makefile (copiado al directorio de servlets, etc); asi que delegamos la + * creacion del thread a la gxclassr donde se llama al metodo a ser ejecutado + * Adem�s ahora manejamos un pool de threads en el submit + */ + public void callSubmit(final int id, Object [] submitParms) + { + com.genexus.util.SubmitThreadPool.submit(this, id, submitParms, context.submitCopy()); + } + + /** Este metodo es redefinido por la clase GX generada cuando hay submits + */ + public void submit(int id, Object [] submitParms, ModelContext ctx){ + } + public void submit(int id, Object [] submitParms){ + } + public void submitReorg(int id, Object [] submitParms) throws SQLException { + } +} diff --git a/java/src/main/java/com/genexus/webpanels/GXWebReport.java b/java/src/main/java/com/genexus/GXWebReport.java similarity index 97% rename from java/src/main/java/com/genexus/webpanels/GXWebReport.java rename to java/src/main/java/com/genexus/GXWebReport.java index 1978f2b51..d6f084b6d 100644 --- a/java/src/main/java/com/genexus/webpanels/GXWebReport.java +++ b/java/src/main/java/com/genexus/GXWebReport.java @@ -1,12 +1,11 @@ -package com.genexus.webpanels; +package com.genexus; -import com.genexus.ModelContext; -import com.genexus.ProcessInterruptedException; import com.genexus.db.UserInformation; import com.genexus.internet.HttpContext; import com.genexus.reports.GXReportMetadata; import com.genexus.reports.IReportHandler; import com.genexus.reports.PDFReportItext; +import com.genexus.webpanels.GXWebProcedure; public abstract class GXWebReport extends GXWebProcedure { diff --git a/java/src/main/java/com/genexus/GXutil.java b/java/src/main/java/com/genexus/GXutil.java index dbae021f1..32c18f70d 100644 --- a/java/src/main/java/com/genexus/GXutil.java +++ b/java/src/main/java/com/genexus/GXutil.java @@ -15,6 +15,7 @@ import com.genexus.util.*; import json.org.json.JSONObject; +import org.apache.commons.lang.StringUtils; public final class GXutil { @@ -1704,11 +1705,19 @@ public static String pagingSelect(String select) public static String getEncryptedSignature( String value, String key) { - return Encryption.encrypt64(CommonUtil.getHash( com.genexus.security.web.WebSecurityHelper.StripInvalidChars(value), CommonUtil.SECURITY_HASH_ALGORITHM), key); + return Encryption.encrypt64(CommonUtil.getHash( StripInvalidChars(value), CommonUtil.SECURITY_HASH_ALGORITHM), key); } public static boolean checkEncryptedSignature( String value, String hash, String key) { - return CommonUtil.getHash( com.genexus.security.web.WebSecurityHelper.StripInvalidChars(value), CommonUtil.SECURITY_HASH_ALGORITHM).equals(Encryption.decrypt64(hash, key)); + return CommonUtil.getHash( StripInvalidChars(value), CommonUtil.SECURITY_HASH_ALGORITHM).equals(Encryption.decrypt64(hash, key)); + } + + public static String StripInvalidChars(String input) + { + if (input == null) + return input; + String output = input.replaceAll("[\u0000-\u001f]", ""); + return StringUtils.strip(output); } public static String buildWSDLFromHttpClient(com.genexus.internet.HttpClient GXSoapHTTPClient, String wsdlURL) diff --git a/java/src/main/java/com/genexus/GxRestService.java b/java/src/main/java/com/genexus/GxRestService.java index 2e848c6f2..51da992ba 100644 --- a/java/src/main/java/com/genexus/GxRestService.java +++ b/java/src/main/java/com/genexus/GxRestService.java @@ -4,59 +4,43 @@ import java.text.SimpleDateFormat; import java.util.Date; -import com.genexus.servlet.IServletContext; -import com.genexus.servlet.http.IHttpServletRequest; -import com.genexus.servlet.http.IHttpServletResponse; - import com.genexus.diagnostics.core.ILogger; -import com.genexus.internet.HttpContext; import com.genexus.internet.MsgList; import com.genexus.security.GXResult; import com.genexus.security.GXSecurityProvider; -import com.genexus.webpanels.GXWebObjectBase; +import com.genexus.servlet.IServletContext; +import com.genexus.servlet.http.IHttpServletRequest; +import com.genexus.servlet.http.IHttpServletResponse; import com.genexus.webpanels.HttpContextWeb; import json.org.json.JSONException; import json.org.json.JSONObject; -abstract public class GxRestService extends GXWebObjectBase -{ +abstract public class GxRestService extends GXObjectBase { private static ILogger logger = null; protected JSONObject errorJson; protected boolean error = false; - protected boolean useAuthentication = false; protected String gamError; protected boolean forbidden = false; protected String permissionPrefix; protected abstract boolean IntegratedSecurityEnabled(); protected abstract int IntegratedSecurityLevel(); + protected String ExecutePermissionPrefix(){ return ""; } protected boolean IsSynchronizer() - { - return false; - } - - public boolean isMasterPage() { return false; } - - protected static final int SECURITY_HIGH = 2; protected static final int SECURITY_LOW = 1; protected static final String POST = "POST"; - - public GxRestService() - { - super(); - } - protected HttpContext restHttpContext; + protected HttpContextWeb restHttpContext; protected com.genexus.ws.rs.core.IResponseBuilder builder; protected void init(String requestMethod) { @@ -101,15 +85,15 @@ private void initLogger(IServletContext myContext) { public void webExecute( ) { - } + } protected void cleanup() { - GXutil.setThreadTimeZone(ModelContext.getModelContext().getClientTimeZone()); - super.cleanup(); + GXutil.setThreadTimeZone(ModelContext.getModelContext().getClientTimeZone()); + super.cleanup(); super.finallyCleanup(); - WrapperUtils.requestBodyThreadLocal.remove(); - } + WrapperUtils.requestBodyThreadLocal.remove(); + } public void ErrorCheck(IGxSilentTrn trn) { @@ -212,7 +196,7 @@ public boolean isAuthenticated(IHttpServletRequest myServletRequest) public boolean isAuthenticated(IHttpServletRequest myServletRequest, String synchronizer) { boolean validSynchronizer = false; - try{ + try { if (synchronizer!= null && !synchronizer.equals("")) { synchronizer = synchronizer.toLowerCase() + "_services_rest"; @@ -221,13 +205,13 @@ public boolean isAuthenticated(IHttpServletRequest myServletRequest, String sync packageName += "."; Class synchronizerClass = Class.forName(packageName + synchronizer); GxRestService synchronizerRestService = (GxRestService) synchronizerClass.getConstructor().newInstance(); - if (synchronizerRestService!=null && synchronizerRestService.IsSynchronizer()){ + if (synchronizerRestService!=null && synchronizerRestService.IsSynchronizer()) { validSynchronizer = true; return isAuthenticated(myServletRequest, synchronizerRestService.IntegratedSecurityLevel(), synchronizerRestService.IntegratedSecurityEnabled(), synchronizerRestService.ExecutePermissionPrefix()); } } return false; - } + } catch(Exception e) { logger.error("Could not check user authenticated", e); diff --git a/java/src/main/java/com/genexus/internet/HttpAjaxContext.java b/java/src/main/java/com/genexus/internet/HttpAjaxContext.java deleted file mode 100644 index 314367583..000000000 --- a/java/src/main/java/com/genexus/internet/HttpAjaxContext.java +++ /dev/null @@ -1,921 +0,0 @@ - -package com.genexus.internet; - -import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Stack; -import java.util.Collections; -import java.util.Arrays; - -import com.genexus.IGXAssigned; -import com.genexus.common.interfaces.IGXWebGrid; -import com.genexus.diagnostics.core.ILogger; -import com.genexus.diagnostics.core.LogManager; -import com.genexus.webpanels.DynAjaxEventContext; -import com.genexus.common.interfaces.IGXWebRow; - -import json.org.json.IJsonFormattable; -import json.org.json.JSONArray; -import json.org.json.JSONException; -import json.org.json.JSONObject; - -public abstract class HttpAjaxContext -{ - public static final ILogger logger = LogManager.getLogger(HttpAjaxContext.class); - private JSONArray AttValues = new JSONArray(); - private JSONArray PropValues = new JSONArray(); - protected JSONObject HiddenValues = new JSONObject(); - protected JSONObject Messages = new JSONObject(); - private JSONObject WebComponents = new JSONObject(); - private Hashtable LoadCommands = new Hashtable<>(); - private ArrayList Grids = new ArrayList(); - private Hashtable DicGrids = new Hashtable(); - private JSONObject ComponentObjects = new JSONObject(); - protected GXAjaxCommandCollection commands = new GXAjaxCommandCollection(); - protected IGXWebRow _currentGridRow = null; - protected JSONArray StylesheetsToLoad = new JSONArray(); - - protected boolean bCloseCommand = false; - protected boolean Redirected = false; - protected boolean ajaxRefreshAsGET = false; - protected String formCaption = ""; - private Object[] returnParms = new Object[] {}; - private Object[] returnParmsMetadata = new Object[] {}; - - private Stack cmpContents = new Stack<>(); - - private String _ajaxOnSessionTimeout = "Ignore"; - public void setAjaxOnSessionTimeout( String ajaxOnSessionTimeout){ this._ajaxOnSessionTimeout = ajaxOnSessionTimeout;} - public String ajaxOnSessionTimeout(){ return _ajaxOnSessionTimeout;} - - DynAjaxEventContext dynAjaxEventContext = new DynAjaxEventContext(); - - public DynAjaxEventContext getDynAjaxEventContext() { - return dynAjaxEventContext; - } - - public abstract boolean isMultipartContent(); - public abstract void ajax_rsp_assign_prop_as_hidden(String Control, String Property, String Value); - - public abstract boolean isSpaRequest(); - public abstract boolean isSpaRequest(boolean ignoreFlag); - private boolean isJsOutputEnabled = true; - - public void disableJsOutput() - { - isJsOutputEnabled = false; - } - - public void enableJsOutput() - { - isJsOutputEnabled = true; - } - - public boolean isJsOutputEnabled() - { - return isJsOutputEnabled; - } - - public boolean isRedirected() - { - return Redirected; - } - - public boolean isCloseCommand() - { - return bCloseCommand; - } - - protected int nCmpDrawLvl = 0; - public MsgList GX_msglist = new MsgList(); - - private void doAjaxRefresh(String command) - { - try - { - String refreshMethod = "POST"; - if (ajaxRefreshAsGET) - { - refreshMethod = "GET"; - } - appendAjaxCommand(command, refreshMethod); - } - catch (JSONException ex) - { - } - } - - public void doAjaxRefresh() - { - doAjaxRefresh("refresh"); - } - - public void doAjaxRefreshForm() - { - doAjaxRefresh("refresh_form"); - } - - public void doAjaxRefreshCmp(String sPrefix) - { - try - { - appendAjaxCommand("cmp_refresh", sPrefix); - } - catch (JSONException ex) - { - } - } - - public void doAjaxLoad(int SId, IGXWebRow row) - { - try - { - JSONObject JSONRow = new JSONObject(); - JSONRow.put("grid", SId); - JSONRow.put("props", row.getParentGrid().GetJSONObject()); - JSONRow.put("values", row.getParentGrid().GetValues()); - appendLoadData(SId, JSONRow); - } - catch (JSONException ex) - { - } - } - - public void doAjaxAddLines(int SId, int lines) - { - try - { - JSONObject JSONData = new JSONObject(); - JSONData.put("grid", SId); - JSONData.put("count", lines); - appendAjaxCommand("addlines", JSONData); - } - catch (JSONException ex) - { - } - } - - public void doAjaxSetFocus(String controlName) - { - try - { - appendAjaxCommand("set_focus", controlName); - } - catch (JSONException ex) - { - } - } - - protected Object[] getWebReturnParms() - { - return this.returnParms; - } - - protected Object[] getWebReturnParmsMetadata() - { - return this.returnParmsMetadata; - } - - public void setWebReturnParms(Object[] retParms) - { - this.returnParms = retParms; - } - - public void setWebReturnParmsMetadata(Object[] retParmsMetadata) - { - this.returnParmsMetadata = retParmsMetadata; - } - - public void appendAjaxCommand(String cmdType, Object cmdData) throws JSONException - { - commands.AppendCommand(new GXAjaxCommand(cmdType, cmdData)); - } - - public void appendLoadData(int SId, JSONObject Data) throws JSONException - { - LoadCommands.put(SId, Data); - } - - public void executeUsercontrolMethod(String CmpContext, boolean IsMasterPage, String containerName, String methodName, String input, Object[] parms) - { - GXUsercontrolMethod method = new GXUsercontrolMethod(CmpContext, IsMasterPage, containerName, methodName, input, parms); - commands.AppendCommand(new GXAjaxCommand("ucmethod", method.GetJSONObject())); - } - - public void setExternalObjectProperty(String CmpContext, boolean IsMasterPage, String containerName, String propertyName, Object value) - { - JSONObject obj = new JSONObject(); - try - { - obj.put("CmpContext", CmpContext); - obj.put("IsMasterPage", IsMasterPage); - obj.put("ObjectName", containerName); - obj.put("PropertyName", propertyName); - obj.put("Value", value); - } catch (JSONException ex) { - } - commands.AppendCommand(new GXAjaxCommand("exoprop", obj)); - } - - public void executeExternalObjectMethod(String CmpContext, boolean IsMasterPage, String containerName, String methodName, Object[] parms, boolean isEvent) - { - JSONObject obj = new JSONObject(); - try - { - obj.put("CmpContext", CmpContext); - obj.put("IsMasterPage", IsMasterPage); - obj.put("ObjectName", containerName); - obj.put("Method", methodName); - obj.put("Parms", HttpAjaxContext.ObjArrayToJSONArray(parms)); - obj.put("IsEvent", isEvent); - } catch (JSONException ex) { - } - commands.AppendCommand(new GXAjaxCommand("exomethod", obj)); - } - - protected void addPrintReportCommand(String reportFile, String printerRule) - { - JSONObject obj = new JSONObject(); - try - { - obj.put("reportFile", reportFile); - obj.put("printerRule", printerRule); - } - catch (JSONException e) { } - commands.AppendCommand(new GXAjaxCommand("print", obj)); - } - - protected void ajax_addCmpContent( String content) - { - if (nCmpDrawLvl > 0) - (cmpContents.peek()).addContent(content); - } - - public void ajax_rspStartCmp( String CmpId) - { - if (isJsOutputEnabled) - { - try - { - WebComponents.put(CmpId, ""); - } - catch (JSONException ex) { } - } - nCmpDrawLvl++; - cmpContents.push(new GXCmpContent(CmpId)); - } - - public void ajax_rspEndCmp() - { - nCmpDrawLvl--; - try - { - GXCmpContent cmp = cmpContents.pop(); - WebComponents.put(cmp.getId(), cmp.getContent()); - if (isSpaRequest()) - { - if (nCmpDrawLvl > 0) - (cmpContents.peek()).addContent(cmp.getContent()); - } - } - catch (JSONException ex) - { - } - } - - private JSONObject getGxObject(JSONArray array, String CmpContext, boolean IsMasterPage) - { - try - { - JSONObject obj; - int len = array.length(); - for(int i=0; i= 0) - return; - } - if (Control.equals("FORM") && Property.equals("Caption")) - { - formCaption = Value; - } - JSONObject obj = getGxObject(PropValues, CmpContext, IsMasterPage); - if (obj != null) - { - JSONObject ctrlProps = getControlProps(obj, Control); - if (ctrlProps != null) - { - ctrlProps.put(Property, Value); - } - } - com.genexus.internet.HttpContext webContext = (HttpContext) com.genexus.ModelContext.getModelContext().getHttpContext(); - if (webContext != null && !webContext.isAjaxRequest()) - { - ajax_rsp_assign_hidden(Control + "_" + Property.substring(0, 1) + Property.substring(1).toLowerCase(), Value); - } - } - catch (JSONException e) { - } - } - } - } - - public void ajax_rsp_assign_uc_prop(String CmpContext, boolean IsMasterPage, String Control, String Property, String Value) - { - ajax_rsp_assign_prop(CmpContext, IsMasterPage, Control, Property, Value, true); - ajax_rsp_assign_prop_as_hidden(Control, Property, Value); - } - - public void ajax_rsp_assign_boolean_hidden(String Property, Boolean Value) - { - ajax_rsp_assign_hidden(Property, (Object)Value); - } - - public void ajax_rsp_assign_hidden(String Property, String Value) - { - ajax_rsp_assign_hidden(Property, (Object)Value); - } - - private void ajax_rsp_assign_hidden(String Property, Object Value) - { - try { - if (_currentGridRow != null) - _currentGridRow.AddHidden(Property, Value); - else - HiddenValues.put(Property, Value); - } - catch (JSONException e) { - } - } - - public void ajax_rsp_assign_hidden_sdt( String SdtName, Object SdtObj) - { - try { - if (SdtObj instanceof IGxJSONAble) - { - HiddenValues.put(SdtName, ((IGxJSONAble)SdtObj).GetJSONObject()); - } - else - { - if (SdtObj.getClass().isArray()) - { - try { - HiddenValues.put(SdtName, ObjArrayToJSONArray(SdtObj)); - } - catch(ClassCastException e){ - logger.error(String.format("Could not serialize Object '%s' to JSON", SdtName), e); - HiddenValues.put(SdtName, SdtObj); - } - } - } - } - catch (JSONException e) { - logger.error(String.format("Could not serialize Object '%s' to JSON", SdtName), e); - } - } - - public void ajax_rsp_assign_grid(String gridName, IGXWebGrid gridObj) - { - Object jsonObj = ((IGxJSONAble) gridObj).GetJSONObject(); - Grids.add(jsonObj); - } - - public void ajax_rsp_assign_grid(String gridName, IGXWebGrid gridObj, String Control) - { - Object jsonObj = ((IGxJSONAble) gridObj).GetJSONObject(); - if (DicGrids.containsKey(Control)) { - Grids.set(DicGrids.get(Control), jsonObj); - } - else - { - Grids.add(jsonObj); - DicGrids.put(Control, Grids.size() - 1); - } - } - - public void ajax_rsp_clear(){ - PropValues = new JSONArray(); - } - - private boolean shouldLogAjaxControlProperty(String property) - { - return isJsOutputEnabled || (isSpaRequest() && property == "Enabled"); - } - - @Deprecated - public void AddComponentObject(String cmpCtx, String objName) - { - AddComponentObject(cmpCtx, objName, true); - } - - public void AddComponentObject(String cmpCtx, String objName, boolean justCreated) - { - try { - com.genexus.internet.HttpContext webContext = (HttpContext) com.genexus.ModelContext.getModelContext().getHttpContext(); - if (justCreated) - { - try { - webContext.DeletePostValuePrefix(cmpCtx); - } - catch (Exception e) { - logger.error("Could not delete post value prefix", e); - } - } - ComponentObjects.put(cmpCtx, objName); - } - catch (JSONException e) { - } - } - - public void SendComponentObjects() - { - try { - HiddenValues.put("GX_CMP_OBJS", ComponentObjects); - } - catch (JSONException e) { - } - } - - protected void AddThemeHidden(String theme) - { - try { - HiddenValues.put("GX_THEME", theme); - } - catch (JSONException e) { - } - } - - public void AddStylesheetsToLoad() - { - if (StylesheetsToLoad.length() > 0) - { - try { - HiddenValues.put("GX_STYLE_FILES", StylesheetsToLoad); - } - catch (JSONException e) { - } - } - } - - public void SaveComponentMsgList( String sPrefix) - { - try { - Messages.put(sPrefix, GX_msglist.GetJSONObject()); - } - catch (JSONException e) { - } - } - - public String getJSONContainerResponse(IGxJSONAble Container) { - - GXJSONObject jsonCmdWrapper = new GXJSONObject(isMultipartContent()); - try - { - jsonCmdWrapper.put("gxHiddens", HiddenValues); - jsonCmdWrapper.put("gxContainer", Container.GetJSONObject()); - } - catch (JSONException e) - { - } - return jsonCmdWrapper.toString(); - } - - protected String getJSONResponsePrivate(String cmpContext) - { - GXJSONObject jsonCmdWrapper = new GXJSONObject(isMultipartContent()); - try - { - Collections.reverse(Arrays.asList(Grids)); - JSONArray JSONGrids = new JSONArray(Grids); - if (commands.AllowUIRefresh()) - { - if (cmpContext == null || cmpContext.equals("")) - { - cmpContext = "MAIN"; - } - SaveComponentMsgList(cmpContext); - jsonCmdWrapper.put("gxProps", PropValues); - jsonCmdWrapper.put("gxHiddens", HiddenValues); - jsonCmdWrapper.put("gxValues", AttValues); - jsonCmdWrapper.put("gxMessages", Messages); - jsonCmdWrapper.put("gxComponents", WebComponents); - jsonCmdWrapper.put("gxGrids", JSONGrids); - } - for(Enumeration loadCmds = LoadCommands.keys(); loadCmds.hasMoreElements();) - { - appendAjaxCommand("load", LoadCommands.get(loadCmds.nextElement())); - } - if (commands.getCount() > 0) - { - jsonCmdWrapper.put("gxCommands", commands.getJSONArray()); - } - } - catch (JSONException e) - { - } - return jsonCmdWrapper.toString(); - } - - public String getJSONResponse(String cmpContext) - { - if (isCloseCommand() || isRedirected()) - return ""; - return getJSONResponsePrivate(cmpContext); - } - - public String getJSONResponse() - { - return getJSONResponse(""); - } - - public static Object[] createArrayFromArrayObject(Object o) { - if(!o.getClass().getComponentType().isPrimitive()) - return (Object[])o; - - int element_count = Array.getLength(o); - Object elements[] = new Object[element_count]; - - for(int i = 0; i < element_count; i++){ - elements[i] = Array.get(o, i); - } - - return elements; - } - - public static JSONArray ObjArrayToJSONArray(Object parms) - { - return ObjArrayToJSONArray(createArrayFromArrayObject(parms)); - } - - public static JSONArray ObjArrayToJSONArray(Object[] parms) - { - JSONArray inputs = new JSONArray(); - for (int i = 0; i < parms.length; i++) - { - Object parm = parms[i]; - if (parm instanceof IGxJSONAble) - { - inputs.put(((IGxJSONAble)parm).GetJSONObject()); - } - else if (parm.getClass().isArray()) - { - inputs.put(ObjArrayToJSONArray((Object[])parm)); - } - else - { - inputs.put(parm); - } - } - return inputs; - } - - public String getWebReturnParmsJS() - { - return ObjArrayToJSONArray(this.getWebReturnParms()).toString(); - } - - public String getWebReturnParmsMetadataJS() - { - return ObjArrayToJSONArray(this.getWebReturnParmsMetadata()).toString(); - } - - class GXCmpContent - { - private String id; - private String content; - - public GXCmpContent(String id) - { - this.id = id; - this.content = ""; - } - - public String getId() - { - return id; - } - - public void addContent(String content) - { - this.content += content; - } - - public String getContent() - { - return content; - } - } - - class GXAjaxCommand - { - private String[] canManyCmds = new String[] { "print", "load", "popup", "refresh", "ucmethod", "cmp_refresh", "addlines", "set_focus", "calltarget", "exoprop", "exomethod", "refresh_form" }; - private String type; - private Object data; - - public GXAjaxCommand(String type) - { - this.type = type; - this.data = ""; - } - - public GXAjaxCommand(String type, Object data) - { - this.type = type; - this.data = data; - } - - public String getType() - { - return type; - } - - public void setData(Object data) - { - this.data = data; - } - - public Object getData() - { - return data; - } - - public JSONObject getJSONObject() - { - JSONObject jObj = new JSONObject(); - try { - jObj.put(type, data); - } catch (JSONException ex) { - } - return jObj; - } - - public boolean canHaveMany() - { - for (int i = 0; i < canManyCmds.length; i++) - { - if (type.equals(canManyCmds[i])) - { - return true; - } - } - return false; - } - - public boolean equals(Object obj) - { - if (obj instanceof GXAjaxCommand) - { - if (!canHaveMany()) - { - return (type.equalsIgnoreCase(((GXAjaxCommand)obj).getType())); - } - } - return super.equals(obj); - } - - public String toString() - { - return "{ type:" + type + ", data:" + data + " }"; - } - } - - public class GXUsercontrolMethod implements IGxJSONAble - { - JSONObject wrapper; - - public GXUsercontrolMethod(String CmpContext, boolean IsMasterPage, String containerName, String methodName, String output, Object[] parms) - { - wrapper = new JSONObject(); - AddObjectProperty("CmpContext", CmpContext); - AddObjectProperty("IsMasterPage", new Boolean(IsMasterPage)); - AddObjectProperty("Control", containerName); - AddObjectProperty("Method", methodName); - AddObjectProperty("Output", output); - AddObjectProperty("Parms", HttpAjaxContext.ObjArrayToJSONArray(parms)); - } - - public JSONArray GetParmsJArray(Object[] parms) - { - JSONArray inputs = new JSONArray(); - for (int i = 0; i < parms.length; i++) - { - Object parm = parms[i]; - if (parm instanceof IGxJSONAble) - { - inputs.put(((IGxJSONAble)parm).GetJSONObject()); - } - else - { - inputs.put(parm); - } - } - return inputs; - } - - public void AddObjectProperty(String name, Object prop) - { - try - { - wrapper.put(name, prop); - } catch (JSONException ex) { - } - } - - public Object GetJSONObject(boolean includeState) - { - return GetJSONObject(); - } - - public Object GetJSONObject() - { - return wrapper; - } - - public void FromJSONObject(IJsonFormattable obj) - { - } - - public String ToJavascriptSource() - { - return wrapper.toString(); - } - - public void tojson() - { - } - } - - class GXAjaxCommandCollection - { - private ArrayList commands; - private boolean allowUIRefresh; - - public GXAjaxCommandCollection() - { - commands = new ArrayList<>(); - allowUIRefresh = true; - } - - public int getCount() - { - return commands.size(); - } - - public boolean AllowUIRefresh() - { - return allowUIRefresh; - } - - public void AppendCommand(GXAjaxCommand cmd) - { - GXAjaxCommand cmd1 = GetCommand(cmd); - if (cmd1 == null) - { - if (allowUIRefresh) - { - allowUIRefresh = cmd.canHaveMany(); - } - commands.add(cmd); - } - else - { - cmd1.setData(cmd.getData()); - } - } - - private GXAjaxCommand GetCommand(GXAjaxCommand cmd) - { - int cIdx = commands.indexOf(cmd); - if (cIdx > 0) - { - return commands.get(cIdx); - } - return null; - } - - public JSONArray getJSONArray() - { - JSONArray jArr = new JSONArray(); - for(int i=0; i javascriptSources = new Vector<>(); - private Vector deferredFragments = new Vector(); - private Vector styleSheets = new Vector<>(); - private HashSet deferredJavascriptSources = new HashSet(); private boolean responseCommited = false; - private boolean wrapped = false; - private int drawGridsAtServer = -1; + protected boolean wrapped = false; + protected int drawGridsAtServer = -1; private boolean ignoreSpa = false; - private String serviceWorkerFileName = "service-worker.js"; - private Boolean isServiceWorkerDefinedFlag = null; - - private String webAppManifestFileName = "manifest.json"; - private Boolean isWebAppManifestDefinedFlag = null; - private static HashMap cachedMessages = new HashMap(); - private String currentLanguage = null; - private Vector userStyleSheetFiles = new Vector(); - private String themekbPrefix; - private String themestyleSheet; - private String themeurlBuildNumber; - - private boolean isServiceWorkerDefined() - { - if (isServiceWorkerDefinedFlag == null) - { - isServiceWorkerDefinedFlag = Boolean.valueOf(checkFileExists(serviceWorkerFileName)); - } - return isServiceWorkerDefinedFlag == Boolean.valueOf(true); - } - - private boolean isWebAppManifestDefined() - { - if (isWebAppManifestDefinedFlag == null) - { - isWebAppManifestDefinedFlag = Boolean.valueOf(checkFileExists(webAppManifestFileName)); - } - return isWebAppManifestDefinedFlag == Boolean.valueOf(true); - } + protected String currentLanguage = null; public boolean isOutputEnabled() { @@ -247,22 +185,6 @@ protected void copyCommon(HttpContext ctx) ctx.responseCommited = responseCommited; } - public static final int TYPE_RESET = 0; - public static final int TYPE_SUBMIT = 1; - public static final int TYPE_BUTTON = 2; - - public static final int BROWSER_OTHER = 0; - public static final int BROWSER_IE = 1; - public static final int BROWSER_NETSCAPE = 2; - public static final int BROWSER_OPERA = 3; - public static final int BROWSER_UP = 4; - public static final int BROWSER_POCKET_IE = 5; - public static final int BROWSER_FIREFOX = 6; - public static final int BROWSER_CHROME = 7; - public static final int BROWSER_SAFARI = 8; - public static final int BROWSER_EDGE = 9; - public static final int BROWSER_INDEXBOT = 20; - public abstract void cleanup(); public abstract String getResourceRelative(String path); public abstract String getResourceRelative(String path, boolean includeBasePath); @@ -295,7 +217,6 @@ protected void copyCommon(HttpContext ctx) public abstract void setDefaultPath(String path); public abstract String getBrowserVersion(); public abstract Object getSessionValue(String name); - public abstract void webPutSessionValue(String name, Object value); public abstract void webPutSessionValue(String name, long value); public abstract void webPutSessionValue(String name, double value); @@ -326,11 +247,8 @@ protected void copyCommon(HttpContext ctx) public abstract void changePostValue(String ctrl, String value); public abstract boolean isFileParm( String parm); public abstract void parseGXState(JSONObject tokenValues); - - public abstract void deletePostValue(String ctrl); - public abstract void DeletePostValuePrefix(String sPrefix); - - + public abstract void deletePostValue(String ctrl); + public abstract void DeletePostValuePrefix(String sPrefix); public abstract HttpResponse getHttpResponse(); public abstract HttpRequest getHttpRequest(); public abstract void setHttpRequest(HttpRequest httprequest); @@ -339,246 +257,11 @@ protected void copyCommon(HttpContext ctx) public abstract void setRequest(IHttpServletRequest request); public abstract Hashtable getPostData(); public abstract WebSession getWebSession(); - public abstract void redirect(String url); - public abstract void redirect(String url, boolean SkipPushUrl); public abstract void setStream() ; public abstract void flushStream(); - - public abstract void closeHtmlHeader(); - public abstract boolean getHtmlHeaderClosed(); - public abstract void ajax_rsp_command_close(); - public abstract void dispatchAjaxCommands(); - public abstract boolean isHttpContextNull(); public abstract boolean isHttpContextWeb(); - - public void AddDeferredFrags() - { - Enumeration vEnum = deferredFragments.elements(); - while(vEnum.hasMoreElements()) - { - writeTextNL(vEnum.nextElement()); - } - } - - public void ClearJavascriptSources() { - javascriptSources.clear(); - } - - public void AddJavascriptSource(String jsSrc, String urlBuildNumber, boolean userDefined, boolean isInlined) - { - if(!javascriptSources.contains(jsSrc)) - { - urlBuildNumber = getURLBuildNumber(jsSrc, urlBuildNumber); - javascriptSources.add(jsSrc); - String queryString = urlBuildNumber; - String attributes = ""; - if (userDefined) - { - queryString = ""; - attributes = "data-gx-external-script"; - } - String fragment = "" ; - if (isAjaxRequest() || isInlined || jsSrc == "jquery.js" || jsSrc == "gxcore.js") - { - writeTextNL(fragment); - } - else - { - deferredFragments.add(fragment); - } - // After including jQuery, include all the deferred Javascript files - if (jsSrc.equals("jquery.js")) - { - for (String deferredJsSrc : deferredJavascriptSources) - { - AddJavascriptSource(deferredJsSrc, "", false, true); - } - } - // After including gxgral, set the Service Worker Url if one is defined - if (jsSrc.equals("gxgral.js") && isServiceWorkerDefined()) - { - writeTextNL(""); - } - } - } - - public void addWebAppManifest() - { - if (isWebAppManifestDefined()) - { - writeTextNL(""); - } - } - - private boolean checkFileExists(String fileName) - { - boolean fileExists = false; - try - { - File file = new File(getDefaultPath() + staticContentBase + fileName); - fileExists = file.exists() && file.isFile(); - com.genexus.diagnostics.Log.info("Searching if file exists (" + fileName + "). Found: " + String.valueOf(fileExists)); - } - catch (Exception e) - { - fileExists = false; - com.genexus.diagnostics.Log.info("Failed searching for a file (" + fileName + ")"); - } - return fileExists; - } - - - public void AddDeferredJavascriptSource(String jsSrc, String urlBuildNumber) - { - deferredJavascriptSources.add(oldConvertURL(jsSrc) + urlBuildNumber); - } - - - private String FetchCustomCSS() - { - String cssContent; - cssContent = ApplicationContext.getcustomCSSContent().get(getRequest().getServletPath()); - if (cssContent == null) - { - String path = getRequest().getServletPath().replaceAll(".*/", "") + ".css"; - try(InputStream istream = context.packageClass.getResourceAsStream(path)) - { - - if (istream == null) - { - cssContent = ""; - } - else { - //BOMInputStream bomInputStream = new BOMInputStream(istream);// Avoid using BOMInputStream because of runtime error (java.lang.NoSuchMethodError: org.apache.commons.io.IOUtils.length([Ljava/lang/Object;)I) issue 94611 - //cssContent = IOUtils.toString(bomInputStream, "UTF-8"); - cssContent = PrivateUtilities.BOMInputStreamToStringUTF8(istream); - } - } - catch ( Exception e) { - cssContent = ""; - } - ApplicationContext.getcustomCSSContent().put(getRequest().getServletPath(), cssContent); - } - return cssContent; - } - - public void CloseStyles() - { - String cssContent = FetchCustomCSS(); - boolean bHasCustomContent = ! cssContent.isEmpty(); - if (bHasCustomContent && !styleSheets.contains(getRequest().getServletPath())) - { - writeTextNL(""); - styleSheets.add(getRequest().getServletPath()); - } - String[] referencedFiles = ThemeHelper.getThemeCssReferencedFiles(PrivateUtilities.removeExtension(themestyleSheet)); - for (int i=0; i @import url(\"" + sUncachedURL + "\") layer(" + sLayerName + ");"); - } - else - { - writeTextNL(" 0) - { - return true; - } - return false; - } - - private String getAjaxEncryptionKey() - { - if(getSessionValue(Encryption.AJAX_ENCRYPTION_KEY) == null) - { - if (!recoverEncryptionKey()) - { - webPutSessionValue(Encryption.AJAX_ENCRYPTION_KEY, Encryption.getRijndaelKey()); - } - } - return (String)getSessionValue(Encryption.AJAX_ENCRYPTION_KEY); - } - - private boolean recoverEncryptionKey() - { - if (getSessionValue(Encryption.AJAX_ENCRYPTION_KEY) == null) - { - String clientKey = getRequest().getHeader(Encryption.AJAX_SECURITY_TOKEN); - if (clientKey != null && clientKey.trim().length() > 0) - { - boolean candecrypt[]=new boolean[1]; - clientKey = Encryption.decryptRijndael(Encryption.GX_AJAX_PRIVATE_IV + clientKey, Encryption.GX_AJAX_PRIVATE_KEY, candecrypt); - if (candecrypt[0]) - { - webPutSessionValue(Encryption.AJAX_ENCRYPTION_KEY, clientKey); - return true; - }else - { - return false; - } - } - } - return false; - } - - public String DecryptAjaxCall(String encrypted) - { - validEncryptedParm = false; - if (isGxAjaxRequest()) - { - String key = getAjaxEncryptionKey(); - boolean candecrypt[] = new boolean[1]; - String decrypted = Encryption.decryptRijndael(encrypted, key, candecrypt); - validEncryptedParm = candecrypt[0]; - if (!validEncryptedParm) - { - CommonUtil.writeLogln( String.format("403 Forbidden error. Could not decrypt Ajax parameter: '%s' with key: '%s'", encrypted, key)); - sendResponseStatus(403, "Forbidden action"); - return ""; - } - if (validEncryptedParm && !getRequestMethod().equalsIgnoreCase("post")) - { - setQueryString(decrypted); - decrypted = GetNextPar(); - } - return decrypted; - } - return encrypted; - } - - public boolean IsValidAjaxCall() - { - return IsValidAjaxCall(true); - } - - public boolean IsValidAjaxCall(boolean insideAjaxCall) - { - if (insideAjaxCall && !validEncryptedParm) - { - CommonUtil.writeLogln( "Failed IsValidAjaxCall 403 Forbidden action"); - sendResponseStatus(403, "Forbidden action"); - return false; - } - else if (!insideAjaxCall && isGxAjaxRequest() && !isFullAjaxMode() && ajaxOnSessionTimeout().equalsIgnoreCase("Warn")) - { - sendResponseStatus(440, "Session timeout"); - return false; - } - return true; - } public void sendResponseStatus(int statusCode, String statusDescription) { if (statusCode < 200 || statusCode >= 300) { getResponse().setHeader("Content-Encoding", ""); - if (statusCode != GXWebObjectBase.SPA_NOT_SUPPORTED_STATUS_CODE) + if (statusCode != SPA_NOT_SUPPORTED_STATUS_CODE) { CommonUtil.writeLog("sendResponseStatus " + Integer.toString(statusCode) + " " + statusDescription); } @@ -896,11 +389,6 @@ public void sendResponseStatus(int statusCode, String statusDescription) disableOutput(); } - private void sendReferer() - { - ajax_rsp_assign_hidden("sCallerURL", org.owasp.encoder.Encode.forUri(getReferer())); - } - private static String CLIENT_ID_HEADER = "GX_CLIENT_ID"; public void initClientId() @@ -926,78 +414,10 @@ public boolean useSecurityTokenValidation() { return ((Preferences)this.context.getPreferences()).getProperty("ValidateSecurityToken", "y").equals("y"); } - - protected void addNavigationHidden() - { - if (this.isLocalStorageSupported()) - { - try { - HiddenValues.put("GX_CLI_NAV", "true"); - } catch (JSONException e) { - } - GXNavigationHelper nav = this.getNavigationHelper(); - if (nav.count() > 0) - { - String sUrl = this.getRequestNavUrl().trim(); - String popupLevel = nav.getUrlPopupLevel(sUrl); - try { - HiddenValues.put("GX_NAV", nav.toJSonString(popupLevel)); - } catch (JSONException e) { - } - nav.deleteStack(popupLevel); - } - } - } - - public void SendWebComponentState() - { - AddStylesheetsToLoad(); - } - - public void SendState() - { - sendReferer(); - sendWebSocketParms(); - addNavigationHidden(); - AddThemeHidden(this.getTheme()); - AddStylesheetsToLoad(); - if (isSpaRequest()) - { - writeTextNL(""); - } - else - { - if (this.drawGridsAtServer()) - { - writeTextNL(""); - } - skipLines(1); - String value = HiddenValues.toString(); - if (useBase64ViewState()) - { - try{ - value = Codecs.base64Encode(value, "UTF8"); - }catch(Exception ex){} - writeTextNL(""); - } - writeText("
"); - } - } - - private void sendWebSocketParms() - { - if (!this.isAjaxRequest() || isSpaRequest()) - { - ajax_rsp_assign_hidden("GX_WEBSOCKET_ID", clientId); - } - } - public String getEncryptedSignature( String value, String key) { - return encrypt64(CommonUtil.getHash( com.genexus.security.web.WebSecurityHelper.StripInvalidChars(value), CommonUtil.SECURITY_HASH_ALGORITHM), key); + return encrypt64(CommonUtil.getHash( GXutil.StripInvalidChars(value), CommonUtil.SECURITY_HASH_ALGORITHM), key); } public String encrypt64(String value, String key) @@ -1032,85 +452,6 @@ public String decrypt64(String value, String key) return sRet; } - public void SendAjaxEncryptionKey() - { - if(!encryptionKeySended) - { - String key = getAjaxEncryptionKey(); - ajax_rsp_assign_hidden(Encryption.AJAX_ENCRYPTION_KEY, key); - ajax_rsp_assign_hidden(Encryption.AJAX_ENCRYPTION_IV, Encryption.GX_AJAX_PRIVATE_IV); - try - { - ajax_rsp_assign_hidden(Encryption.AJAX_SECURITY_TOKEN, Encryption.encryptRijndael(key, Encryption.GX_AJAX_PRIVATE_KEY)); - } - catch(Exception exc) {} - encryptionKeySended = true; - } - } - - public void SendServerCommands() - { - try { - if (!isAjaxRequest() && commands.getCount() > 0) - { - HiddenValues.put("GX_SRV_COMMANDS", commands.getJSONArray()); - } - } - catch (JSONException e) { - } - } - - public void ajax_req_read_hidden_sdt(String jsonStr, Object SdtObj) - { - try - { - IJsonFormattable jsonObj; - if (jsonStr.startsWith("[")) - jsonObj = new JSONArray(jsonStr); - else - jsonObj = new JSONObject(jsonStr); - ((IGxJSONAble)SdtObj).FromJSONObject(jsonObj); - } - catch(JSONException exc) {} - } - - public void ajax_rsp_assign_prop_as_hidden(String Control, String Property, String Value) - { - if (!this.isAjaxRequest()) - { - ajax_rsp_assign_hidden(Control + "_" + Property.substring(0, 1) + Property.substring(1).toLowerCase(), Value); - } - } - - public boolean IsSameComponent(String oldName, String newName) - { - if(oldName.trim().equalsIgnoreCase(newName.trim())) - { - return true; - } - else - { - if(newName.trim().toLowerCase().startsWith(oldName.trim().toLowerCase() + "?")) - { - return true; - } - else - { - String packageName = context.getPackageName(); - String qoldName; - String qnewName; - - if ( (oldName.indexOf(packageName) != 0) || (newName.indexOf(packageName) != 0)) - { - qoldName = (oldName.indexOf(packageName) != 0) ? packageName + "." + oldName : oldName; - qnewName = (newName.indexOf(packageName) != 0) ? packageName + "." + newName : newName; - return IsSameComponent(qoldName, qnewName); - } - } - } - return false; - } - public void webGetSessionValue(String name, byte[] value) { Object o = getSessionValue(name); @@ -1163,205 +504,19 @@ public void webGetSessionValue(String name, String[] value) value[0] = (String) o; } } -/* - public void webGetSessionValue(String name, java.util.Date[] value) - { - Object o = getSessionValue(name); - if (o != null) - System.arraycopy(o, 0, value, 0, value.length); - } - - public void webGetSessionValue(String name, byte[][] value) - { - Object o = getSessionValue(name); - if (o != null) - System.arraycopy(o, 0, value, 0, value.length); - } - - public void webGetSessionValue(String name, short[][] value) - { - Object o = getSessionValue(name); - if (o != null) - System.arraycopy(o, 0, value, 0, value.length); - } - - public void webGetSessionValue(String name, int[][] value) - { - Object o = getSessionValue(name); - if (o != null) - System.arraycopy(o, 0, value, 0, value.length); - } - - public void webGetSessionValue(String name, long[][] value) - { - Object o = getSessionValue(name); - if (o != null) - System.arraycopy(o, 0, value, 0, value.length); - } - - public void webGetSessionValue(String name, float[][] value) - { - Object o = getSessionValue(name); - if (o != null) - System.arraycopy(o, 0, value, 0, value.length); - } - - public void webGetSessionValue(String name, double[][] value) - { - Object o = getSessionValue(name); - if (o != null) - System.arraycopy(o, 0, value, 0, value.length); - } - - public void webGetSessionValue(String name, String[][] value) - { - Object o = getSessionValue(name); - if (o != null) - System.arraycopy(o, 0, value, 0, value.length); - } - - public void webGetSessionValue(String name, java.util.Date[][] value) - { - Object o = getSessionValue(name); - if (o != null) - System.arraycopy(o, 0, value, 0, value.length); - } -*/ public String getSubscriberId() { return getHeader("HTTP_X_UP_SUBNO"); } - public byte isMobileBrowser() - { - String accept = getHeader("HTTP_ACCEPT"); - - return (accept.indexOf("wap") >= 0 || accept.indexOf("hdml") >= 0)?0: (byte) 1; - } - - public void writeValueComplete(String text) - { - writeValueComplete(text, true, true, true); - } - - public void writeValueSpace(String text) - { - writeValueComplete(text, false, false, true); - } - - public void writeValueEnter(String text) - { - writeValueComplete(text, false, true, false); - } - - /** Este writeValue tiene en consideracion los espacios consecutivos, - * los enter y los tabs - */ - public void writeValueComplete(String text, boolean cvtTabs, boolean cvtEnters, boolean cvtSpaces) - { - StringBuilder sb = new StringBuilder(); - boolean lastCharIsSpace = true; // Asumo que al comienzo el lastChar era space - for (int i = 0; i < text.length(); i++) - { - char currentChar = text.charAt(i); - switch (currentChar) - { - case (char) 34: - sb.append("""); - break; - case (char) 38: - sb.append("&"); - break; - case (char) 60: - sb.append("<"); - break; - case (char) 62: - sb.append(">"); - break; - case '\t': - sb.append(cvtTabs ? "    " : ("" + currentChar)); - break; - case '\r': - if (cvtEnters && text.length() > i + 1 && text.charAt(i+1) == '\n'){ - sb.append(cvtEnters ? "
" : ("" + currentChar)); - i++; - } - break; - case '\n': - sb.append(cvtEnters ? "
" : ("" + currentChar)); - break; - case ' ': - sb.append((lastCharIsSpace && cvtSpaces) ? " " : " "); - break; - default: - sb.append("" + currentChar); - } - lastCharIsSpace = currentChar == ' '; - } - writeText(sb.toString()); - } - - public void writeValue(String text) - { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < text.length(); i++) - { - char currentChar = text.charAt(i); - - switch (currentChar) - { - case '"': - sb.append("""); - break; - case '&': - sb.append("&"); - break; - case '<': - sb.append("<"); - break; - case '>': - sb.append(">"); - break; - default: - sb.append(currentChar); - } - } - writeText(sb.toString()); - } - - public void skipLines(long num) - { - for(; num > 0; num --) - { - writeText("\n"); - } - } - public void setOutputStream(OutputStream out) { this.out = out; } - public void writeTextNL(String text) - { - writeText(text + "\n"); - } - public boolean useUtf8 = false; - public void writeText(String text) - { - if (getResponseCommited()) - return; - if (isEnabled == false) - { - ajax_addCmpContent(text); - return; - } - _writeText(text); - } - public void _writeText(String text) { _writeText(text, false); @@ -1420,12 +575,6 @@ public void setWriter(PrintWriter writer) this.writer = writer; } -/* public PrintWriter getWriter() - { - return writer; - } - -*/ public void closeWriter() { if (writer != null) @@ -1447,11 +596,6 @@ public void closeOutputStream() } } - public MsgList getMessageList() - { - return GX_msglist; - } - public void setBuffered(boolean buffered) { this.buffered = buffered; @@ -1480,7 +624,7 @@ public void setUserId(String userId) this.userId = userId; } - private String staticContentBase = ""; + protected String staticContentBase = ""; public void setStaticContentBase(String staticContentBase) { this.staticContentBase = staticContentBase; @@ -1684,47 +828,6 @@ public String getLanguage() } return currentLanguage; } - public String htmlEndTag(HTMLElement element) - { - HTMLDocType docType = context.getClientPreferences().getDOCTYPE(); - if ((docType == HTMLDocType.HTML4 || docType == HTMLDocType.NONE || docType == HTMLDocType.HTML4S) && - (element == HTMLElement.IMG || - element == HTMLElement.INPUT || - element == HTMLElement.META || - element == HTMLElement.LINK)) - return ">"; - else if (element == HTMLElement.OPTION) - if (docType == HTMLDocType.XHTML1 || docType == HTMLDocType.HTML5) - return ""; - else - return ""; - else - return "/>"; - } - public String htmlDocType() - { - HTMLDocType docType = context.getClientPreferences().getDOCTYPE(); - switch (docType) - { - case HTML4: - if (context.getClientPreferences().getDOCTYPE_DTD()) - return ""; - else - return ""; - case HTML4S: - if (context.getClientPreferences().getDOCTYPE_DTD()) - return ""; - else - return ""; - case XHTML1: - if (context.getClientPreferences().getDOCTYPE_DTD()) - return ""; - else - return ""; - case HTML5: return ""; - default: return ""; - } - } public int setLanguage(String language) { @@ -1836,4 +939,18 @@ public boolean willRedirect() { return wjLoc != null && wjLoc.trim().length() != 0; } + + public void readJsonSdtValue(String jsonStr, Object SdtObj) + { + try + { + IJsonFormattable jsonObj; + if (jsonStr.startsWith("[")) + jsonObj = new JSONArray(jsonStr); + else + jsonObj = new JSONObject(jsonStr); + ((IGxJSONAble)SdtObj).FromJSONObject(jsonObj); + } + catch(JSONException exc) {} + } } diff --git a/java/src/main/java/com/genexus/internet/HttpContextNull.java b/java/src/main/java/com/genexus/internet/HttpContextNull.java index 6ff8cdad9..4e3b2ed01 100644 --- a/java/src/main/java/com/genexus/internet/HttpContextNull.java +++ b/java/src/main/java/com/genexus/internet/HttpContextNull.java @@ -409,27 +409,20 @@ public void setHttpRequest(HttpRequest httprequest) this.httprequest = httprequest; } - public WebSession getWebSession() { return webSession; } - public void redirect(String url) {} - public void redirect(String url, boolean SkipPushUrl) {} - public void ajax_rsp_command_close(){}; - public void dispatchAjaxCommands() {}; - public void closeHtmlHeader() {}; - public boolean getHtmlHeaderClosed() { return false; } - public void setStream(){} public void flushStream(){} public String cgiGetFileName(String parm) {return "";} public String cgiGetFileType(String parm) {return "";} public void getMultimediaValue(String internalName, String[] blobVar, String[] uriVar) { blobVar[0] = ""; uriVar[0] = ""; } public void cleanup() {} - public boolean isMultipartContent() { return false; } public boolean isHttpContextNull() {return true;} public boolean isHttpContextWeb() {return false;} + + public void redirect(String url) {} } diff --git a/java/src/main/java/com/genexus/reports/GXReport.java b/java/src/main/java/com/genexus/reports/GXReport.java index 8b896005f..add2dbd88 100644 --- a/java/src/main/java/com/genexus/reports/GXReport.java +++ b/java/src/main/java/com/genexus/reports/GXReport.java @@ -49,24 +49,16 @@ public static byte openGXReport(String document) } return 0; } - - protected void setPrintAtClient() - { - setPrintAtClient(""); - } - protected void setPrintAtClient(String printerRule) + public String setPrintAtClient() { String blobPath = com.genexus.Preferences.getDefaultPreferences().getBLOB_PATH(); String fileName = com.genexus.PrivateUtilities.getTempFileName(blobPath, "clientReport", getOutputType() == OUTPUT_PDF ? "pdf":"gxr"); getPrinter().GxSetDocName(fileName); getPrinter().GxSetDocFormat("GXR"); - if (httpContext != null) - { - httpContext.printReportAtClient(fileName, printerRule); - } com.genexus.webpanels.BlobsCleaner.getInstance().addBlobFile(fileName); + return fileName; } public void setPrinter(IReportHandler reportHandler) diff --git a/java/src/main/java/com/genexus/reports/GXReportText.java b/java/src/main/java/com/genexus/reports/GXReportText.java index fda7707a8..7de41326b 100644 --- a/java/src/main/java/com/genexus/reports/GXReportText.java +++ b/java/src/main/java/com/genexus/reports/GXReportText.java @@ -84,25 +84,17 @@ protected void setOutput(String fileName) setOutput(System.out); } } - - protected void setPrintAtClient() - { - setPrintAtClient(""); - } - protected void setPrintAtClient(String printerRule) - { - printAtClient = true; - String blobPath = com.genexus.Preferences.getDefaultPreferences().getBLOB_PATH(); - String fileName = com.genexus.PrivateUtilities.getTempFileName(blobPath, "clientReport", "txt"); - - setOutput(fileName); - if (httpContext != null) - { - httpContext.printReportAtClient(fileName, printerRule); - } - com.genexus.webpanels.BlobsCleaner.getInstance().addBlobFile(fileName); - } + public String setPrintAtClient() + { + printAtClient = true; + String blobPath = com.genexus.Preferences.getDefaultPreferences().getBLOB_PATH(); + String fileName = com.genexus.PrivateUtilities.getTempFileName(blobPath, "clientReport", "txt"); + + setOutput(fileName); + com.genexus.webpanels.BlobsCleaner.getInstance().addBlobFile(fileName); + return fileName; + } class AsciiPrintWriter extends PrintWriter { diff --git a/java/src/main/java/com/genexus/webpanels/GXOAuthAccessToken.java b/java/src/main/java/com/genexus/webpanels/GXOAuthAccessToken.java index cb9e31389..b40a4766c 100644 --- a/java/src/main/java/com/genexus/webpanels/GXOAuthAccessToken.java +++ b/java/src/main/java/com/genexus/webpanels/GXOAuthAccessToken.java @@ -127,8 +127,8 @@ protected void doExecute(HttpContext context) throws Exception } String OauthRealm = "OAuth realm=\"" + context.getRequest().getServerName() + "\"" + ",error_code=\"" + gamError + "\"" + ",error_description=\"" + messagePermissionEncoded + "\""; context.getResponse().addHeader("WWW-Authenticate", OauthRealm); - SetError(gamError, messagePermission); - context.writeText(errorJson.toString()); + SetError(gamError, messagePermission); + ((HttpContextWeb) context).writeText(errorJson.toString()); context.getResponse().flushBuffer(); return; } @@ -144,7 +144,7 @@ protected void doExecute(HttpContext context) throws Exception context.getResponse().addHeader("location", redirectURL[0]); JSONObject jObj = new JSONObject(); jObj.put("Location", redirectURL[0]); - context.writeText(jObj.toString()); + ((HttpContextWeb) context).writeText(jObj.toString()); context.getResponse().flushBuffer(); return; } @@ -152,7 +152,7 @@ protected void doExecute(HttpContext context) throws Exception { context.getResponse().setContentType("application/json"); context.getResponse().setStatus(200); - context.writeText((String)gamout.getjsonString()); + ((HttpContextWeb) context).writeText((String)gamout.getjsonString()); context.getResponse().flushBuffer(); return; } diff --git a/java/src/main/java/com/genexus/webpanels/GXOAuthLogout.java b/java/src/main/java/com/genexus/webpanels/GXOAuthLogout.java index 9c7a927ac..bbe1b5530 100644 --- a/java/src/main/java/com/genexus/webpanels/GXOAuthLogout.java +++ b/java/src/main/java/com/genexus/webpanels/GXOAuthLogout.java @@ -40,7 +40,7 @@ protected void doExecute(HttpContext context) throws Exception { jObj.put("code", statusCode[0]); } - context.writeText(jObj.toString()); + ((HttpContextWeb) context).writeText(jObj.toString()); context.getResponse().flushBuffer(); return; } diff --git a/java/src/main/java/com/genexus/webpanels/GXOAuthUserInfo.java b/java/src/main/java/com/genexus/webpanels/GXOAuthUserInfo.java index 93ccfc255..17b148c78 100644 --- a/java/src/main/java/com/genexus/webpanels/GXOAuthUserInfo.java +++ b/java/src/main/java/com/genexus/webpanels/GXOAuthUserInfo.java @@ -29,7 +29,7 @@ protected void doExecute(HttpContext context) throws Exception { context.getResponse().setContentType("application/json"); context.getResponse().setStatus(200); - context.writeText(user[0]); + ((HttpContextWeb) context).writeText(user[0]); context.getResponse().flushBuffer(); return; } diff --git a/java/src/main/java/com/genexus/webpanels/GXObjectUploadServices.java b/java/src/main/java/com/genexus/webpanels/GXObjectUploadServices.java index a10adf505..094cf19e9 100644 --- a/java/src/main/java/com/genexus/webpanels/GXObjectUploadServices.java +++ b/java/src/main/java/com/genexus/webpanels/GXObjectUploadServices.java @@ -39,7 +39,7 @@ protected void doExecute(HttpContext context) throws Exception ModelContext.getModelContext().setHttpContext(context); context.setContext(modelContext); - if (context.isMultipartContent()) + if (((HttpContextWeb) context).isMultipartContent()) { context.setContentType("text/plain"); FileItemCollection postedFiles = context.getHttpRequest().getPostedparts(); @@ -67,7 +67,7 @@ protected void doExecute(HttpContext context) throws Exception } JSONObject jObjResponse = new JSONObject(); jObjResponse.put("files", jsonArray); - context.writeText(jObjResponse.toString()); + ((HttpContextWeb) context).writeText(jObjResponse.toString()); context.getResponse().flushBuffer(); } else @@ -86,7 +86,7 @@ protected void doExecute(HttpContext context) throws Exception context.getResponse().setContentType("application/json"); context.getResponse().setStatus(201); context.getResponse().setHeader("GeneXus-Object-Id", keyId); - context.writeText(jObj.toString()); + ((HttpContextWeb) context).writeText(jObj.toString()); context.getResponse().flushBuffer(); } else { diff --git a/java/src/main/java/com/genexus/webpanels/GXWebException.java b/java/src/main/java/com/genexus/webpanels/GXWebException.java deleted file mode 100644 index b8d066463..000000000 --- a/java/src/main/java/com/genexus/webpanels/GXWebException.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.genexus.webpanels; - -public class GXWebException extends RuntimeException -{ - /** - * - */ - private static final long serialVersionUID = 1L; - Exception e; - String msg; - - public GXWebException(Exception e) - { - this.e = e; - this.msg = e.getMessage(); - } - - public GXWebException(String text) - { - this.msg = text; - - } - - public String toString() - { - if (e != null) - return e.toString() + " / " + msg; - return msg; - } -} \ No newline at end of file diff --git a/java/src/main/java/com/genexus/webpanels/GXWebObjectBase.java b/java/src/main/java/com/genexus/webpanels/GXWebObjectBase.java deleted file mode 100644 index 7e779aae9..000000000 --- a/java/src/main/java/com/genexus/webpanels/GXWebObjectBase.java +++ /dev/null @@ -1,689 +0,0 @@ -package com.genexus.webpanels; - -import java.math.BigDecimal; -import java.sql.SQLException; -import java.util.TimeZone; - -import com.genexus.*; -import com.genexus.configuration.ConfigurationManager; -import com.genexus.diagnostics.GXDebugInfo; -import com.genexus.diagnostics.GXDebugManager; -import org.apache.commons.lang.StringUtils; - -import com.genexus.ModelContext; -import com.genexus.db.Namespace; -import com.genexus.db.UserInformation; -import com.genexus.diagnostics.core.ILogger; -import com.genexus.diagnostics.core.LogManager; -import com.genexus.internet.GXInternetConstants; -import com.genexus.internet.HttpContext; -import com.genexus.internet.IGxJSONSerializable; -import com.genexus.security.GXSecurityProvider; -import com.genexus.security.web.SecureTokenHelper; -import com.genexus.security.web.WebSecurityHelper; -import com.genexus.util.GXTimeZone; - -import com.genexus.GXRestServiceWrapper; - -public abstract class GXWebObjectBase extends GXRestServiceWrapper implements IErrorHandler, GXInternetConstants, ISubmitteable -{ - public static final ILogger logger = LogManager.getLogger(GXWebObjectBase.class); - - private static String GX_SPA_GXOBJECT_RESPONSE_HEADER = "X-GXOBJECT"; - protected static String GX_SPA_MASTERPAGE_HEADER = "X-SPA-MP"; - public static int SPA_NOT_SUPPORTED_STATUS_CODE = 530; - protected static String GX_AJAX_MULTIPART_ID = "GXAjaxMultipart"; - - protected boolean IntegratedSecurityEnabled() { return false;} - protected int IntegratedSecurityLevel() { return 0;} - protected String IntegratedSecurityPermissionPrefix() {return "";} - - protected static final int SECURITY_GXOBJECT = 3; - protected static final int SECURITY_HIGH = 2; - protected static final int SECURITY_LOW = 1; - - public abstract void webExecute(); - public abstract boolean isMasterPage(); - - protected ModelContext context; - protected HttpContext httpContext; - protected LocalUtil localUtil; - protected int remoteHandle = -1; - - protected UserInformation ui; - protected TimeZone timeZone; - - public Object getParm( Object[] parms, int index) - { - return parms[index]; - } - - public GXWebObjectBase() - { - } - - /** - * Este constructor se usa cuando aun no tengo un ModelContext ni remoteHandle, pero - * si tengo el HttpContext. Basicamente es el punto de entrada en los servlets. - */ - public GXWebObjectBase(HttpContext httpContext, Class contextClass) - { - init(httpContext, contextClass); - } - - /** - * Este constructor se usa cuando aun no tengo un ModelContext ni remoteHandle, pero - * si tengo el HttpContext. Basicamente es el punto de entrada en los servlets. - */ - public GXWebObjectBase(HttpContext httpContext) - { - init(httpContext, getClass()); - } - - /** - * Este constructor se usa cuando ya tengo un ModelContext y remoteHandle. - * Basicamente es el punto de entrada para webcomponents, webwrappers, etc. - */ - public GXWebObjectBase(int remoteHandle, ModelContext context) - { - this.context = context; - - ui = (UserInformation) GXObjectHelper.getUserInformation(context, remoteHandle); - this.remoteHandle = ui.getHandle(); - - initState(context, ui); - } - - /*** - * Return the DefaultTheme for all WebPanels and Transactions. - * @return - */ - @SuppressWarnings("unused") - protected void initializeTheme() { - this.httpContext.setDefaultTheme(ConfigurationManager.getValue("Theme")); - } - - protected void init(HttpContext httpContext, Class contextClass) - { - // @gusbro:06/06/05 - // El JDK.15 mantiene un TimeZone default por cada Thread, por lo cual el hack que haciemos - // en la gxutil de setear el timeZone falla en motores de servlets - // Lo que hacemos es setear el default aqui, ademas para ser mas 'prolijos' volvemos al valor - // original al finalizar el request (esto ultimo ya no se hace, porque puede traer problemas) - timeZone = GXTimeZone.getDefaultOriginal(); - this.context = new ModelContext(contextClass); - context.setHttpContext(httpContext); - - new WebApplicationStartup().init(contextClass, httpContext); - - ApplicationContext.getInstance().setPoolConnections(!Namespace.createNamespace(context).isRemoteGXDB()); - - ui = (UserInformation) GXObjectHelper.getUserInformation(context, -1); - ui.setAutoDisconnect(false); - remoteHandle = ui.getHandle(); - - initState(context, ui); - } - - protected void initState(ModelContext context, UserInformation ui) - { - localUtil = ui.getLocalUtil(); - httpContext = (HttpContext) context.getHttpContext(); - httpContext.setContext( context); - httpContext.setCompression(getCompressionMode()); - } - - protected boolean getCompressionMode() - { - return context.getClientPreferences().getCOMPRESS_HTML(); - } - - protected boolean CheckCmpSecurityAccess() - { - boolean[] flag = new boolean[]{false}; - boolean[] permissionFlag = new boolean[]{false}; - String permissionPrefix = IntegratedSecurityPermissionPrefix(); - com.genexus.internet.HttpRequest req = ((HttpContext)ModelContext.getModelContext().getHttpContext()).getHttpRequest(); - if (req == null) - return false; - String reqUrl = req.getRequestURL(); - ModelContext modelContext = ModelContext.getModelContext(getClass()); - if (IntegratedSecurityLevel() == SECURITY_LOW || IntegratedSecurityLevel() == SECURITY_GXOBJECT) - { - GXSecurityProvider.getInstance().checksession(-2, modelContext, reqUrl, permissionFlag); - } - if (IntegratedSecurityLevel() != SECURITY_LOW && IntegratedSecurityLevel() != SECURITY_GXOBJECT) - { - GXSecurityProvider.getInstance().checksessionprm(-2, modelContext, reqUrl, permissionPrefix, flag, permissionFlag); - } - return permissionFlag[0]; - } - - protected void preExecute() - { - httpContext.responseContentType("text/html"); //default Content-Type - httpContext.initClientId(); - } - - protected void sendCacheHeaders() - { - if (httpContext.isSpaRequest()) { - httpContext.getResponse().setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); - httpContext.getResponse().setHeader("Pragma", "no-cache"); - httpContext.getResponse().setHeader("Expires", "0"); - } - else { - httpContext.getResponse().addDateHeader("Expires", 0); - httpContext.getResponse().addDateHeader("Last-Modified", 0); - if (this instanceof GXWebReport && ((GXWebReport)this).getOutputType()==GXWebReport.OUTPUT_PDF) { - httpContext.getResponse().addHeader("Cache-Control", "must-revalidate,post-check=0, pre-check=0"); - //Estos headers se setean por un bug de Reader X que hace que en IE no se vea el reporte cuando esta embebido, - //solo se ve luego de hacer F5. - } - else { - httpContext.getResponse().addHeader("Cache-Control", "max-age=0, no-cache, no-store, must-revalidate"); - } - } - } - - protected void sendAdditionalHeaders() - { - if (httpContext.isSpaRequest()) - sendSpaHeaders(); - if (httpContext.getBrowserType() == HttpContext.BROWSER_IE && !httpContext.isPopUpObject()) - { - String IECompMode = context.getClientPreferences().getIE_COMPATIBILITY(); - if (IECompMode.equals("EmulateIE7") && !httpContext.getBrowserVersion().startsWith("8") ) - return; - if (StringUtils.isNotEmpty(IECompMode)) - httpContext.getResponse().addHeader("X-UA-Compatible", "IE=" + IECompMode); - } - } - - protected void sendSpaHeaders() - { - httpContext.getResponse().setHeader(GX_SPA_GXOBJECT_RESPONSE_HEADER, getPgmname().toLowerCase()); - } - - public void doExecute() throws Exception - { - try - { - if (isSpaRequest() && !isSpaSupported()) - { - httpContext.sendResponseStatus(SPA_NOT_SUPPORTED_STATUS_CODE, "SPA not supported by the object"); - } - else - { - preExecute(); - sendCacheHeaders(); - webExecute(); - sendAdditionalHeaders(); - httpContext.flushStream(); - } - } - catch (Throwable e) - { - handleException(e.getClass().getName(), e.getMessage(), CommonUtil.getStackTraceAsString(e)); - cleanup(); // Antes de hacer el rethrow, hago un cleanup del objeto - throw e; - } - finally - { - finallyCleanup(); - } - } - - protected void finallyCleanup() - { - try - { - if (ui!= null) - ui.disconnect(); - } - catch (java.sql.SQLException e) - { - logger.error("Exception while disconecting ", e); - } - if (httpContext != null) - httpContext.cleanup(); - cleanModelContext(); - } - - private void cleanModelContext() - { - try - { - ((ThreadLocal)com.genexus.CommonUtil.threadCalendar).getClass().getMethod("remove", new Class[0]).invoke(com.genexus.CommonUtil.threadCalendar, (java.lang.Object[])new Class[0]); - ((ThreadLocal)com.genexus.ModelContext.threadModelContext).getClass().getMethod("remove", new Class[0]).invoke(com.genexus.ModelContext.threadModelContext, (java.lang.Object[])new Class[0]); - HTTPClient.StreamDemultiplexor.cleanup(); - } - catch (NoSuchMethodException e) - { - logger.error("cleanModelContext", e); - } - catch (IllegalAccessException e) - { - logger.error("cleanModelContext", e); - } - catch (java.lang.reflect.InvocationTargetException e) - { - logger.error("cleanModelContext " + e.getTargetException(), e); - } - } - - protected void cleanup() - { - Application.cleanupConnection(remoteHandle); - } - - public HttpContext getHttpContext() - { - return httpContext; - } - - public void setHttpContext(HttpContext httpContext) - { - this.httpContext = httpContext; - } - - - public ModelContext getModelContext() - { - return context; - } - - public int getRemoteHandle() - { - return remoteHandle; - } - - public void handleError() - { - new DefaultErrorHandler().handleError(context, remoteHandle); - } - - public ModelContext getContext() - { - return context; - } - - public int setLanguage(String language) - { - int res = GXutil.setLanguage(language, context, ui); - this.localUtil = ui.getLocalUtil(); - return res; - } - public int setTheme(String theme) - { - int res = GXutil.setTheme(theme, context); - return res; - } - public void executeUsercontrolMethod(String CmpContext, boolean IsMasterPage, String containerName, String methodName, String input, Object[] parms) - { - httpContext.executeUsercontrolMethod(CmpContext, IsMasterPage, containerName, methodName, input, parms); - } - - public void setExternalObjectProperty(String CmpContext, boolean IsMasterPage, String containerName, String propertyName, Object value) - { - httpContext.setExternalObjectProperty(CmpContext, IsMasterPage, containerName, propertyName, value); - } - - public void executeExternalObjectMethod(String CmpContext, boolean IsMasterPage, String containerName, String methodName, Object[] parms, boolean isEvent) - { - httpContext.executeExternalObjectMethod(CmpContext, IsMasterPage, containerName, methodName, parms, isEvent); - } - - /** - * @Hack: Tenemos que ejecutar el submit esto en otro thread, pues el submit es asincrono, - * pero si creamos en el fuente generado el codigo del nuevo thread, se va a crear un - * archivo nuevo xxx$N.class al compilar el xxx, que deberia ser tratado especialmente - * en el makefile (copiado al directorio de servlets, etc); asi que delegamos la - * creacion del thread a la gxclassr donde se llama al metodo a ser ejecutado - * Adem�s ahora manejamos un pool de threads en el submit - */ - public void callSubmit(final int id, Object [] submitParms) - { - com.genexus.util.SubmitThreadPool.submit(this, id, submitParms, context.submitCopy()); - } - - /** Este metodo es redefinido por la clase GX generada cuando hay submits - */ - public void submit(int id, Object [] submitParms, ModelContext ctx){ - } - public void submit(int id, Object [] submitParms){ - } - public void submitReorg(int id, Object [] submitParms) throws SQLException{ - } - - protected String formatLink(String jumpURL) - { - return formatLink(jumpURL, new String[]{}); - } - - protected String formatLink(String jumpURL, String[] parms) - { - return formatLink(jumpURL, parms, new String[]{}); - } - - protected String formatLink(String jumpURL, String[] parms, String[] parmsName) - { - return URLRouter.getURLRoute(jumpURL, parms, parmsName, httpContext.getRequest().getContextPath(), context.getPackageName()); - } - - public String getPgmname() - { - return ""; - } - - public String getPgmdesc() - { - return ""; - } - - protected boolean isSpaRequest() - { - return httpContext.isSpaRequest(); - } - - protected boolean isSpaRequest(boolean ignoreFlag) - { - return httpContext.isSpaRequest(ignoreFlag); - } - - protected boolean isSpaSupported() - { - return true; - } - - - protected void validateSpaRequest() - { - // SPA is disabled for objects without master page. However, SPA response headers are sent anyway, so the client side - // replaces the full content using AJAX. - if (isSpaRequest()) - { - httpContext.disableSpaRequest(); - sendSpaHeaders(); - } - } - - - private static String GX_SEC_TOKEN_PREFIX = "GX_AUTH"; - - //Generates only with FullAjax and GAM disabled. - public void sendSecurityToken(String cmpCtx) - { - if (this.httpContext.wjLoc == null || this.httpContext.wjLoc.equals("") ) - { - this.httpContext.ajax_rsp_assign_hidden(getSecurityObjTokenId(cmpCtx), getObjectAccessWebToken(cmpCtx)); - } - } - - private String getSecurityObjTokenId(String cmpCtx) - { - return GX_SEC_TOKEN_PREFIX + "_" + cmpCtx + getPgmname().toUpperCase(); - } - - protected String getPgmInstanceId(String cmpCtx) - { - return String.format("%s%s", cmpCtx, this.getPgmname().toUpperCase()); - } - - private String getObjectAccessWebToken(String cmpCtx) - { - return WebSecurityHelper.sign(getPgmInstanceId(cmpCtx), "", "", SecureTokenHelper.SecurityMode.Sign, getSecretKey()); - } - - private String getSecretKey() - { - //Some random SALT that is different in every GX App installation. Better if changes over time - String hashSalt = com.genexus.Application.getClientContext().getClientPreferences().getREORG_TIME_STAMP(); - return WebUtils.getEncryptionKey(this.context, "") + hashSalt; - } - - private String serialize(double Value, String Pic) - { - return serialize(localUtil.format(Value, Pic)); - } - - private String serialize(int Value, String Pic) - { - return serialize(localUtil.format(Value, Pic)); - } - - private String serialize(short Value, String Pic) - { - return serialize(localUtil.format(Value, Pic)); - } - - private String serialize(long Value, String Pic) - { - return serialize(localUtil.format(Value, Pic)); - } - - private String serialize(Object Value, String Pic) - { - if (!StringUtils.isBlank(Pic)) { - if (Value instanceof Byte) - { - return serialize(localUtil.format(((Byte)Value).intValue(), Pic)); - } - else - { - if (Value instanceof BigDecimal) - { - return serialize(localUtil.format((BigDecimal)Value, Pic)); - } - else - { - if (Value instanceof Integer) - { - return serialize(localUtil.format(((Integer)Value).intValue(), Pic)); - } - else - { - if (Value instanceof Short) - { - return serialize(localUtil.format(((Short)Value).shortValue(), Pic)); - } - else - { - if (Value instanceof Long) - { - return serialize(localUtil.format(((Long)Value).longValue(), Pic)); - } - else - { - if (Value instanceof Double) - { - return serialize(localUtil.format(((Double)Value).doubleValue(), Pic)); - } - else - { - if (Value instanceof Float) - { - return serialize(localUtil.format(((Float)Value).floatValue(), Pic)); - } - else - { - if (Value instanceof java.util.Date) - { - return serialize(localUtil.format((java.util.Date)Value, Pic)); - } - else - { - if (Value instanceof String) - { - return serialize(localUtil.format((String)Value, Pic)); - } - } - } - } - } - } - } - } - } - } - return serialize(Value); - } - - private String serialize(Object Value) { - String strValue = ""; - if (Value instanceof BigDecimal){ - strValue = Value.toString(); - if (strValue.indexOf(".") != -1) - strValue = strValue.replaceAll("0*$", "").replaceAll("\\.$", ""); - } - else{ - if (Value instanceof java.util.Date){ - strValue = " / / 00:00:00"; - if (!Value.equals(CommonUtil.resetTime( CommonUtil.nullDate()))) { - strValue = new java.text.SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(Value); - } - } - else{ - if (Value instanceof com.genexus.xml.GXXMLSerializable) { - strValue = ((com.genexus.xml.GXXMLSerializable) Value).toJSonString(false); - } - else if (Value instanceof IGxJSONSerializable) { - strValue = ((IGxJSONSerializable) Value).toJSonString(); - } - else { - strValue = Value.toString(); - } - } - } - return strValue; - } - - protected String getSecureSignedToken(String cmpCtx, Object Value) - { - return getSecureSignedToken(cmpCtx, serialize(Value)); - } - - protected String getSecureSignedToken(String cmpCtx, boolean Value) - { - return getSecureSignedToken(cmpCtx, Boolean.toString(Value)); - } - - protected String getSecureSignedToken(String cmpCtx, com.genexus.xml.GXXMLSerializable Value) - { - return getSecureSignedToken(cmpCtx, Value.toJSonString(false)); - } - - protected String getSecureSignedToken(String cmpCtx, String Value) - { - return WebSecurityHelper.sign(getPgmInstanceId(cmpCtx), "", Value, SecureTokenHelper.SecurityMode.Sign, getSecretKey()); - } - - protected boolean verifySecureSignedToken(String cmpCtx, int Value, String picture, String token){ - return verifySecureSignedToken(cmpCtx, serialize(Value, picture), token); - } - - protected boolean verifySecureSignedToken(String cmpCtx, short Value, String picture, String token){ - return verifySecureSignedToken(cmpCtx, serialize(Value, picture), token); - } - - protected boolean verifySecureSignedToken(String cmpCtx, long Value, String picture, String token){ - return verifySecureSignedToken(cmpCtx, serialize(Value, picture), token); - } - - protected boolean verifySecureSignedToken(String cmpCtx, double Value, String picture, String token){ - return verifySecureSignedToken(cmpCtx, serialize(Value, picture), token); - } - - protected boolean verifySecureSignedToken(String cmpCtx, Object Value, String picture, String token){ - return verifySecureSignedToken(cmpCtx, serialize(Value, picture), token); - } - - protected boolean verifySecureSignedToken(String cmpCtx, Object Value, String token){ - return verifySecureSignedToken(cmpCtx, serialize(Value), token); - } - - protected boolean verifySecureSignedToken(String cmpCtx, boolean Value, String token){ - return verifySecureSignedToken(cmpCtx, Boolean.toString(Value), token); - } - - protected boolean verifySecureSignedToken(String cmpCtx, com.genexus.xml.GXXMLSerializable Value, String token){ - return verifySecureSignedToken(cmpCtx, Value.toJSonString(false), token); - } - - protected boolean verifySecureSignedToken(String cmpCtx, String value, String token){ - return WebSecurityHelper.verify(getPgmInstanceId(cmpCtx), "", value, token, getSecretKey()); - } - - protected boolean validateObjectAccess(String cmpCtx) - { - if (this.httpContext.useSecurityTokenValidation()){ - String jwtToken = this.httpContext.getHeader("X-GXAUTH-TOKEN"); - jwtToken = (StringUtils.isBlank(jwtToken) && this.httpContext.isMultipartContent())? - this.httpContext.cgiGet("X-GXAUTH-TOKEN"): - jwtToken; - - if (!verifySecureSignedToken(cmpCtx, "", jwtToken)) - { - this.httpContext.sendResponseStatus(401, "Not Authorized"); - if (this.httpContext.getBrowserType() != HttpContextWeb.BROWSER_INDEXBOT) { - logger.warn(String.format("Validation security token failed for program: %s - '%s'", getPgmInstanceId(cmpCtx), jwtToken )); - } - return false; - } - } - return true; - } - - public void handleException(String gxExceptionType, String gxExceptionDetails, String gxExceptionStack) - { - } - - private GXDebugInfo dbgInfo = null; - protected void trkCleanup() - { - if(dbgInfo != null) - dbgInfo.onCleanup(); - } - - protected void initialize(int objClass, int objId, int dbgLines, long hash) - { - dbgInfo = GXDebugManager.getInstance().getDbgInfo(context, objClass, objId, dbgLines, hash); - } - - protected void trk(int lineNro) - { - if(dbgInfo != null) - dbgInfo.trk(lineNro); - } - - protected void trk(int lineNro, int lineNro2) - { - if(dbgInfo != null) - dbgInfo.trk(lineNro, lineNro2); - } - - protected void trkrng(int lineNro, int lineNro2) - { - trkrng(lineNro, 0, lineNro2, 0); - } - - protected void trkrng(int lineNro, int colNro, int lineNro2, int colNro2) - { - if(dbgInfo != null) - dbgInfo.trkRng(lineNro, colNro, lineNro2, colNro2); - } - - protected void callWebObject(String url) - { - httpContext.wjLoc = url; - } - - - public void popup(String url) - { - } - - public void popup(String url, Object[] returnParms) - { - } -} diff --git a/java/src/main/java/com/genexus/webpanels/GXWebObjectStub.java b/java/src/main/java/com/genexus/webpanels/GXWebObjectStub.java index 322aa95a3..bd2b365b4 100644 --- a/java/src/main/java/com/genexus/webpanels/GXWebObjectStub.java +++ b/java/src/main/java/com/genexus/webpanels/GXWebObjectStub.java @@ -82,10 +82,22 @@ private void dumpRequestInfo(HttpContext httpContext) logger.debug(sBuffer.toString()); } - protected void callExecute(String method, IHttpServletRequest req, IHttpServletResponse res) throws ServletException + protected void callExecute(String method, IHttpServletRequest req, IHttpServletResponse res) throws ServletException { + HttpContext httpContext = null; + try + { + httpContext = new HttpContextWeb(method, req, res, getWrappedServletContext()); + callExecute(method, req, res, httpContext); + } + catch (Exception e) + { + handleException(e, httpContext); + } + } + + protected void callExecute(String method, IHttpServletRequest req, IHttpServletResponse res, HttpContext httpContext) throws ServletException { initialize(req, res); - HttpContext httpContext = null; try { String gxcfg = getWrappedServletContext().getInitParameter("gxcfg"); @@ -97,7 +109,6 @@ protected void callExecute(String method, IHttpServletRequest req, IHttpServletR appContext.setServletEngine(true); Application.init(gxcfgClass); } - httpContext = new HttpContextWeb(method, req, res, getWrappedServletContext()); if (logger.isDebugEnabled()) dumpRequestInfo(httpContext); boolean useAuthentication = IntegratedSecurityEnabled(); @@ -166,7 +177,7 @@ else if (IntegratedSecurityLevel() == SECURITY_LOW) GXSecurityProvider.getInstance().checksession(-2, modelContext, reqUrl, flag); if(!flag[0]) { - httpContext.redirect(loginObjectURL, true); + ((HttpContextWeb)httpContext).redirect(loginObjectURL, true); } else { @@ -187,11 +198,11 @@ else if (IntegratedSecurityLevel() == SECURITY_LOW) String notAuthorizedObjectURL = URLRouter.getURLRoute(notAuthorizedObject.toLowerCase(), new String[]{}, new String[]{}, httpContext.getRequest().getContextPath(), modelContext.getPackageName()); if (flag[0]) { - httpContext.redirect(notAuthorizedObjectURL, true); + ((HttpContextWeb)httpContext).redirect(notAuthorizedObjectURL, true); } else { - httpContext.redirect(loginObjectURL, true); + ((HttpContextWeb)httpContext).redirect(loginObjectURL, true); } } } @@ -203,13 +214,18 @@ else if (IntegratedSecurityLevel() == SECURITY_LOW) { if (!res.isCommitted()) res.reset(); - logger.error("Web Execution Error", e); - if (logger.isDebugEnabled() && httpContext != null) - dumpRequestInfo(httpContext); - throw new ServletException(com.genexus.PrivateUtilities.getStackTraceAsString(e)); + handleException(e, httpContext); } } + protected void handleException(Throwable e, HttpContext httpContext) throws ServletException + { + logger.error("Web Execution Error", e); + if (logger.isDebugEnabled() && httpContext != null) + dumpRequestInfo(httpContext); + throw new ServletException(com.genexus.PrivateUtilities.getStackTraceAsString(e)); + } + private void initialize(IHttpServletRequest req, IHttpServletResponse res) { if (logger == null) { logger = com.genexus.specific.java.LogManager.initialize(req.getServletContext().getRealPath("/"), GXWebObjectStub.class); diff --git a/java/src/main/java/com/genexus/webpanels/GXWebProcedure.java b/java/src/main/java/com/genexus/webpanels/GXWebProcedure.java index c83646266..da002d857 100644 --- a/java/src/main/java/com/genexus/webpanels/GXWebProcedure.java +++ b/java/src/main/java/com/genexus/webpanels/GXWebProcedure.java @@ -2,6 +2,7 @@ import java.io.PrintWriter; +import com.genexus.GXObjectBase; import com.genexus.servlet.IServletContext; import com.genexus.servlet.ServletContext; import com.genexus.servlet.http.IHttpServletRequest; @@ -18,7 +19,7 @@ import com.genexus.internet.HttpContext; import com.genexus.ws.GXHandlerChain; -public abstract class GXWebProcedure extends GXWebObjectBase +public abstract class GXWebProcedure extends GXObjectBase { private static final ILogger logger = LogManager.getLogger(GXWebProcedure.class); diff --git a/java/src/main/java/com/genexus/webpanels/HttpContextWeb.java b/java/src/main/java/com/genexus/webpanels/HttpContextWeb.java index a43ccb661..7a6c6e38d 100644 --- a/java/src/main/java/com/genexus/webpanels/HttpContextWeb.java +++ b/java/src/main/java/com/genexus/webpanels/HttpContextWeb.java @@ -42,27 +42,27 @@ public class HttpContextWeb extends HttpContext { HttpResponse httpRes; HttpRequest httpReq; - IServletContext servletContext; + protected IServletContext servletContext; - boolean useOldQueryStringFormat; + protected boolean useOldQueryStringFormat; protected Vector parms; private Hashtable namedParms; private Hashtable postData; private boolean useNamedParameters; private int currParameter; - private IHttpServletRequest request; - private IHttpServletResponse response; - private String requestMethod; + protected IHttpServletRequest request; + protected IHttpServletResponse response; + protected String requestMethod; protected String contentType = ""; - private boolean SkipPushUrl = false; + protected boolean SkipPushUrl = false; + protected boolean Redirected = false; private Hashtable cookies; private boolean streamSet = false; private WebSession webSession; private FileItemCollection fileItemCollection; private IFileItemIterator lstParts; private boolean ajaxCallAsPOST = false; - private boolean htmlHeaderClosed = false; private String sTmpDir; private boolean firstParConsumed = false; @@ -80,6 +80,18 @@ public class HttpContextWeb extends HttpContext { private static final String SAME_SITE_STRICT = "Strict"; private static final String SET_COOKIE = "Set-Cookie"; + public static final int BROWSER_OTHER = 0; + public static final int BROWSER_IE = 1; + public static final int BROWSER_NETSCAPE = 2; + public static final int BROWSER_OPERA = 3; + public static final int BROWSER_UP = 4; + public static final int BROWSER_POCKET_IE = 5; + public static final int BROWSER_FIREFOX = 6; + public static final int BROWSER_CHROME = 7; + public static final int BROWSER_SAFARI = 8; + public static final int BROWSER_EDGE = 9; + public static final int BROWSER_INDEXBOT = 20; + public boolean isMultipartContent() { return ServletFileUpload.isMultipartContent(request); } @@ -183,16 +195,8 @@ public FileItemCollection getPostedparts() { public HttpContext copy() { try { HttpContextWeb o = new HttpContextWeb(requestMethod, request, response, servletContext); - o.cookies = cookies; - o.webSession = webSession; - o.httpRes = httpRes; - o.httpReq = httpReq; - o.postData = postData; - o.parms = parms; - o.namedParms = namedParms; - o.streamSet = streamSet; - o.isCrawlerRequest = o.isCrawlerRequest(); copyCommon(o); + super.copyCommon(o); return o; } catch (java.io.IOException e) { @@ -200,6 +204,18 @@ public HttpContext copy() { } } + protected void copyCommon(HttpContextWeb o) { + o.cookies = cookies; + o.webSession = webSession; + o.httpRes = httpRes; + o.httpReq = httpReq; + o.postData = postData; + o.parms = parms; + o.namedParms = namedParms; + o.streamSet = streamSet; + o.isCrawlerRequest = o.isCrawlerRequest(); + } + public HttpContextWeb(String requestMethod, IHttpServletRequest req, IHttpServletResponse res, IServletContext servletContext) throws IOException { this(ClientContext.getModelContext().getClientPreferences().getProperty("UseNamedParameters", "1").equals("1"), requestMethod, req, res, servletContext); @@ -1256,7 +1272,23 @@ public WebSession getWebSession() { return webSession; } - private void redirect_http(String url) { + public void redirect(String url) { + redirect(url, false); + } + + public void redirect(String url, boolean bSkipPushUrl) { + SkipPushUrl = bSkipPushUrl; + if (!Redirected) { + redirect_impl(url, null); + } + } + + public void redirect_impl(String url, IGXWindow win) { + redirect_http(url); + } + + + protected void redirect_http(String url) { Redirected = true; if (getResponseCommited()) return; @@ -1310,129 +1342,13 @@ private void doForward(IRequestDispatcher dispatcher) throws Exception { dispatcher.forward(getRequest(), getResponse()); } - public void ajax_rsp_command_close() { - bCloseCommand = true; - try { - JSONObject closeParms = new JSONObject(); - closeParms.put("values", ObjArrayToJSONArray(this.getWebReturnParms())); - closeParms.put("metadata", ObjArrayToJSONArray(this.getWebReturnParmsMetadata())); - appendAjaxCommand("close", closeParms); - } catch (JSONException ex) { - } - } - - private void pushUrlSessionStorage() { + protected void pushUrlSessionStorage() { if (context != null && context.getHttpContext().isLocalStorageSupported() && !SkipPushUrl) { context.getHttpContext().pushCurrentUrl(); } SkipPushUrl = false; } - public boolean getHtmlHeaderClosed() { - return this.htmlHeaderClosed; - } - - public void closeHtmlHeader() { - this.htmlHeaderClosed = true; - this.writeTextNL(""); - } - - public void redirect_impl(String url, IGXWindow win) { - if (!isGxAjaxRequest() && !isAjaxRequest() && win == null) { - String popupLvl = getNavigationHelper(false).getUrlPopupLevel(getRequestNavUrl()); - String popLvlParm = ""; - if (popupLvl != "-1") { - popLvlParm = (url.indexOf('?') != -1) ? (useOldQueryStringFormat? "," : "&") : "?"; - popLvlParm += com.genexus.util.Encoder.encodeURL("gxPopupLevel=" + popupLvl + ";"); - } - - if (isSpaRequest(true)) { - pushUrlSessionStorage(); - getResponse().setHeader(GX_SPA_REDIRECT_URL, url + popLvlParm); - sendCacheHeaders(); - } else { - redirect_http(url + popLvlParm); - } - } else { - - try { - if (win != null) { - appendAjaxCommand("popup", win.GetJSONObject()); - } else if (!Redirected) { - JSONObject jsonCmd = new JSONObject(); - jsonCmd.put("url", url); - if (this.wjLocDisableFrm > 0) { - jsonCmd.put("forceDisableFrm", this.wjLocDisableFrm); - } - appendAjaxCommand("redirect", jsonCmd); - if (isGxAjaxRequest()) - dispatchAjaxCommands(); - Redirected = true; - } - } catch (JSONException e) { - redirect_http(url); - } - } - } - - private boolean isDocument(String url) { - try { - int idx = Math.max(url.lastIndexOf('/'), url.lastIndexOf('\\')); - if (idx >= 0 && idx < url.length()) { - url = url.substring(idx + 1); - } - idx = url.indexOf('?'); - String ext = url; - if (idx >= 0) { - ext = ext.substring(0, idx); - } - idx = url.lastIndexOf('.'); - if (idx >= 0) { - ext = ext.substring(idx); - } else { - ext = ""; - } - return (!ext.equals("") && !ext.startsWith(".aspx")); - } catch (Exception ex) { - log.error("isDocument error, url:" + url, ex); - return false; - } - } - - public void redirect(String url) { - redirect(url, false); - } - - public void redirect(String url, boolean bSkipPushUrl) { - SkipPushUrl = bSkipPushUrl; - if (!Redirected) { - redirect_impl(url, null); - } - } - - public void dispatchAjaxCommands() { - Boolean isResponseCommited = getResponseCommited(); - if (!getResponseCommited()) { - String res = getJSONResponsePrivate(""); - if (!isMultipartContent()) { - response.setContentType("application/json"); - } - sendFinalJSONResponse(res); - setResponseCommited(); - } - } - - public void sendFinalJSONResponse(String json) { - boolean isMultipartResponse = !getResponseCommited() && isMultipartContent(); - if (isMultipartResponse) { - _writeText( - ""); - } - public void setStream() { try { if (streamSet) { @@ -1537,6 +1453,13 @@ public void cleanup() { } } + public void writeText(String text) + { + if (getResponseCommited()) + return; + _writeText(text); + } + public boolean isHttpContextNull() {return false;} public boolean isHttpContextWeb() {return true;} -} +} \ No newline at end of file diff --git a/java/src/main/java/com/genexus/webpanels/WebUtils.java b/java/src/main/java/com/genexus/webpanels/WebUtils.java index 25f18c4db..881ef86de 100644 --- a/java/src/main/java/com/genexus/webpanels/WebUtils.java +++ b/java/src/main/java/com/genexus/webpanels/WebUtils.java @@ -324,7 +324,7 @@ public static String getEncodedContentDisposition(String value, int browserType) int filenameIdx = value.toLowerCase().indexOf("filename"); int eqIdx = value.toLowerCase().indexOf("=", filenameIdx); - if(filenameIdx == -1 || eqIdx == -1 || browserType == HttpContext.BROWSER_SAFARI) { //Safari does not support ContentDisposition Header encoded + if(filenameIdx == -1 || eqIdx == -1 || browserType == HttpContextWeb.BROWSER_SAFARI) { //Safari does not support ContentDisposition Header encoded return value; } diff --git a/pom.xml b/pom.xml index 3938a8094..9abd92366 100644 --- a/pom.xml +++ b/pom.xml @@ -8,13 +8,13 @@ parent ${revision}${changelist} pom - + GeneXus Standard Classes (Parent) Core classes for the runtime used by Java and Android apps generated with GeneXus https://github.com/genexuslabs/JavaClasses - 3.1 + 4.0 -SNAPSHOT