All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.faces.facelets.util.DevTools Maven / Gradle / Ivy

/*
 * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package com.sun.faces.facelets.util;

import static com.sun.faces.util.Util.unmodifiableSet;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.sun.faces.RIConstants;
import com.sun.faces.util.Util;

import jakarta.el.Expression;
import jakarta.faces.component.UIComponent;
import jakarta.faces.context.ExternalContext;
import jakarta.faces.context.FacesContext;
import jakarta.faces.context.Flash;

/**
 * Utility class for displaying Facelet error/debug information.
 *
 * 

* The public static methods of this class are exposed as EL functions under the namespace * mojarra.private.functions *

* */ public final class DevTools { private final static String SunNamespace = "http://java.sun.com/mojarra/private/functions"; private final static String JcpNamespace = "http://xmlns.jcp.org/mojarra/private/functions"; private final static String JakartaNamespace = "mojarra.private.functions"; public final static Set NAMESPACES = unmodifiableSet(JakartaNamespace, JcpNamespace, SunNamespace); public final static String DEFAULT_NAMESPACE = JakartaNamespace; private static final Logger LOGGER = Logger.getLogger(DevTools.class.getPackage().getName()); private final static String TS = "<"; private static final String ERROR_TEMPLATE = "META-INF/facelet-dev-error.xml"; private static String[] ERROR_PARTS; private static final String DEBUG_TEMPLATE = "META-INF/facelet-dev-debug.xml"; private static String[] DEBUG_PARTS; // ------------------------------------------------------------ Constructors private DevTools() { throw new IllegalStateException(); } // ---------------------------------------------------------- Public Methods public static void debugHtml(Writer writer, FacesContext faces, Throwable e) throws IOException { init(); Date now = new Date(); for (String ERROR_PART : ERROR_PARTS) { if (null != ERROR_PART) { switch (ERROR_PART) { case "message": writeMessage(writer, e); break; case "trace": writeException(writer, e); break; case "now": writer.write(DateFormat.getDateTimeInstance().format(now)); break; case "tree": writeComponent(writer, faces.getViewRoot()); break; case "vars": writeVariables(writer, faces); break; default: writer.write(ERROR_PART); break; } } } } public static void writeMessage(Writer writer, Throwable e) throws IOException { if (e != null) { String msg = e.getMessage(); if (msg != null) { writer.write(msg.replaceAll("<", TS)); } else { writer.write(e.getClass().getName()); } } } public static void writeException(Writer writer, Throwable e) throws IOException { if (e != null) { StringWriter str = new StringWriter(256); PrintWriter pstr = new PrintWriter(str); e.printStackTrace(pstr); pstr.close(); writer.write(str.toString().replaceAll("<", TS)); } } public static void debugHtml(Writer writer, FacesContext faces) throws IOException { // PENDING - this and debugHtml(Writer, FacesContext, Exception) should // be refactored to share code. init(); Date now = new Date(); for (String DEBUG_PART : DEBUG_PARTS) { if (null != DEBUG_PART) { switch (DEBUG_PART) { case "message": writer.write(faces.getViewRoot().getViewId()); break; case "now": writer.write(DateFormat.getDateTimeInstance().format(now)); break; case "tree": writeComponent(writer, faces.getViewRoot()); break; case "vars": writeVariables(writer, faces); break; default: writer.write(DEBUG_PART); break; } } } } public static void writeVariables(Writer writer, FacesContext faces) throws IOException { ExternalContext ctx = faces.getExternalContext(); writeVariables(writer, ctx.getRequestParameterMap(), "Request Parameters"); if (faces.getViewRoot() != null) { Map viewMap = faces.getViewRoot().getViewMap(false); if (viewMap != null) { writeVariables(writer, viewMap, "View Attributes"); } else { writeVariables(writer, Collections.emptyMap(), "View Attributes"); } } else { writeVariables(writer, Collections.emptyMap(), "View Attributes"); } writeVariables(writer, ctx.getRequestMap(), "Request Attributes"); Flash flash = ctx.getFlash(); try { flash = ctx.getFlash(); } catch (UnsupportedOperationException uoe) { if (LOGGER.isLoggable(Level.FINEST)) { LOGGER.log(Level.FINEST, "Flash not supported", uoe); } } if (flash != null) { writeVariables(writer, flash, "Flash Attributes"); } else { writeVariables(writer, Collections.emptyMap(), "Flash Attributes"); } if (ctx.getSession(false) != null) { writeVariables(writer, ctx.getSessionMap(), "Session Attributes"); } else { writeVariables(writer, Collections.emptyMap(), "Session Attributes"); } writeVariables(writer, ctx.getApplicationMap(), "Application Attributes"); } public static void writeComponent(Writer writer, UIComponent c) throws IOException { writer.write( "
"); if (c == null) { return; } boolean hasChildren = c.getChildCount() > 0 || c.getFacets().size() > 0; writeStart(writer, c, hasChildren); writer.write("
"); if (hasChildren) { if (c.getFacets().size() > 0) { for (Map.Entry entry : c.getFacets().entrySet()) { writer.write("
"); writer.write(""); writer.write((String) entry.getKey()); writer.write(""); writeComponent(writer, (UIComponent) entry.getValue()); writer.write("
"); } } if (c.getChildCount() > 0) { for (UIComponent child : c.getChildren()) { writer.write("
"); writeComponent(writer, child); writer.write("
"); } } writer.write( "
"); writeEnd(writer, c); writer.write("
"); } writer.write("
"); } // --------------------------------------------------------- Private Methods private static void init() throws IOException { if (ERROR_PARTS == null) { ERROR_PARTS = splitTemplate(ERROR_TEMPLATE); } if (DEBUG_PARTS == null) { DEBUG_PARTS = splitTemplate(DEBUG_TEMPLATE); } } private static String[] splitTemplate(String rsc) throws IOException { ClassLoader loader = Util.getCurrentLoader(DevTools.class); String str = ""; InputStream is = null; try { is = loader.getResourceAsStream(rsc); if (is == null) { loader = DevTools.class.getClassLoader(); is = loader.getResourceAsStream(rsc); if (is == null) { throw new FileNotFoundException(rsc); } } ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buff = new byte[512]; int read; while ((read = is.read(buff)) != -1) { baos.write(buff, 0, read); } str = baos.toString(RIConstants.CHAR_ENCODING); } finally { if (null != is) { is.close(); } } return str.split("@@"); } private static void writeVariables(Writer writer, Map vars, String caption) throws IOException { writer.write( ""); boolean written = false; if (!vars.isEmpty()) { SortedMap map = new TreeMap<>(vars); for (Map.Entry entry : map.entrySet()) { String key = entry.getKey(); if (key.indexOf('.') == -1) { writer.write(""); written = true; } } } if (!written) { writer.write(""); } writer.write("
"); writer.write(caption); writer.write( "
NameValue
"); writer.write(key.replaceAll("<", TS)); writer.write(""); writer.write(entry.getValue() == null ? "null" : entry.getValue().toString().replaceAll("<", TS)); writer.write("
None
"); } private static void writeEnd(Writer writer, UIComponent c) throws IOException { if (!isText(c)) { writer.write(TS); writer.write('/'); writer.write(getName(c)); writer.write('>'); } } private final static String[] IGNORE = new String[] { "parent", "rendererType" }; private static void writeAttributes(Writer writer, UIComponent c) { try { BeanInfo info = Introspector.getBeanInfo(c.getClass()); PropertyDescriptor[] pd = info.getPropertyDescriptors(); for (PropertyDescriptor aPd : pd) { if (aPd.getWriteMethod() != null && Arrays.binarySearch(IGNORE, aPd.getName()) < 0) { Method m = aPd.getReadMethod(); try { Object v = m.invoke(c); if (v != null) { if (v instanceof Collection || v instanceof Map || v instanceof Iterator) { continue; } writer.write(" "); writer.write(aPd.getName()); writer.write("=\""); String str; if (v instanceof Expression) { str = ((Expression) v).getExpressionString(); } else { str = v.toString(); } writer.write(str.replaceAll("<", TS)); writer.write("\""); } } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | IOException e) { if (LOGGER.isLoggable(Level.FINEST)) { LOGGER.log(Level.FINEST, "Error writing out attribute", e); } } catch (Exception e) { if (LOGGER.isLoggable(Level.FINEST)) { LOGGER.log(Level.FINEST, "Error writing out attribute", e); } } } } } catch (IntrospectionException e) { LOGGER.log(Level.FINEST, e, () -> "Error writing out attributes"); } } private static void writeStart(Writer writer, UIComponent c, boolean children) throws IOException { if (isText(c)) { String str = c.toString().trim(); writer.write(str.replaceAll("<", TS)); } else { writer.write(TS); writer.write(getName(c)); writeAttributes(writer, c); if (children) { writer.write('>'); } else { writer.write("/>"); } } } private static String getName(UIComponent component) { String componentName = component.getClass().getName(); return componentName.substring(componentName.lastIndexOf('.') + 1); } private static boolean isText(UIComponent c) { return c.getClass().getName().startsWith("com.sun.faces.facelets.compiler"); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy