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

org.wings.plaf.css.AbstractComponentCG Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2000,2005 wingS development team.
 *
 * This file is part of wingS (http://wingsframework.org).
 *
 * wingS is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1
 * of the License, or (at your option) any later version.
 *
 * Please see COPYING for the complete licence.
 */
package org.wings.plaf.css;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.wings.*;
import org.wings.border.SDefaultBorder;
import org.wings.border.SEmptyBorder;
import org.wings.dnd.DragSource;
import org.wings.dnd.DropTarget;
import org.wings.io.Device;
import org.wings.io.StringBuilderDevice;
import org.wings.plaf.*;
import org.wings.plaf.css.script.OnPageRenderedScript;
import org.wings.session.ScriptManager;
import org.wings.util.SessionLocal;

import java.io.IOException;
import java.io.Serializable;
import java.util.Map;

/**
 * Partial CG implementation that is common to all ComponentCGs.
 *
 * @author Holger Engels
 */
public abstract class AbstractComponentCG
    implements ComponentCG, SConstants, Serializable
{
    private static final Logger log = LoggerFactory.getLogger(AbstractComponentCG.class);

    /**
     * An invisible icon / graphic (spacer graphic)
     */
    private static final SIcon BLIND_ICON = new SResourceIcon("org/wings/icons/blind.gif");

    /**
     * Be careful with this shared StringBuilder. Don't use it in situations where unknown code is called, that might
     * use the StringBuilder, too.
     */
    public static final SessionLocal STRING_BUILDER = new SessionLocal() {
        @Override
        protected StringBuilder initialValue() {
            return new StringBuilder();
        }
    };

    protected AbstractComponentCG() {
    }

    /**
     * Renders the default HTML TABLE prefix code for a component. This prefix will handle
     * 
    *
  • All CSS Attrbiutes declared on the SComponent
  • *
  • Components CSS class
  • *
  • Components id
  • *
  • Borders and insets (only if TABLE is used)
  • *
  • Components ToolTip hooks
  • *
  • Components Popup menu hooks
  • *
  • components event id eid
  • *
* * @param device The output device to use * @param component The component to render * @throws IOException on error on the output device */ protected final void writeTablePrefix(Device device, COMPONENT_TYPE component) throws IOException { writePrefix(device, component, true, null); } /** * Renders the default HTML TABLE prefix code for a component. This prefix will handle *
    *
  • All CSS Attrbiutes declared on the SComponent
  • *
  • Components CSS class
  • *
  • Components id
  • *
  • Borders and insets (only if TABLE is used)
  • *
  • Components ToolTip hooks
  • *
  • Components Popup menu hooks
  • *
  • components event id eid
  • *
* * @param device The output device to use * @param component The component to render * @throws IOException on error on the output device */ protected final void writeTablePrefix(Device device, COMPONENT_TYPE component, Map optionalAttributes) throws IOException { writePrefix(device, component, true, optionalAttributes); } /** * Renders the closing suffix for a TABLE based component prefix. * @param device The output device to use * @param component The component to render * @throws IOException on error on the output device */ protected final void writeTableSuffix(Device device, COMPONENT_TYPE component) throws IOException { writeSuffix(device, component, true); } /** * Renders a DIV prefix code for a component. Discouraged * This prefix will handle *
    *
  • All CSS Attrbiutes declared on the SComponent
  • *
  • Components CSS class
  • *
  • Components id
  • *
  • Borders and insets (only if TABLE is used)
  • *
  • Components ToolTip hooks
  • *
  • Components Popup menu hooks
  • *
  • components event id eid
  • *
* * @param device The output device to use * @param component The component to render * @param optionalAttributes A map of additional CSS attributes * @throws IOException on error on the output device */ protected final void writeDivPrefix(Device device, COMPONENT_TYPE component, Map optionalAttributes) throws IOException { writePrefix(device, component, false, optionalAttributes); } /** * Renders the closing suffix for a DIV prefix. * @param device The output device to use * @param component The component to render * @throws IOException on error on the output device */ protected final void writeDivSuffix(Device device, COMPONENT_TYPE component) throws IOException { writeSuffix(device, component, false); } /** * Renders the HTML prefix code for a component. This prefix will handle *
    *
  • All CSS Attrbiutes declared on the SComponent
  • *
  • Components CSS class
  • *
  • Components id
  • *
  • Borders and insets (only if TABLE is used)
  • *
  • Components ToolTip hooks
  • *
  • Components Popup menu hooks
  • *
  • components event id eid
  • *
* * @param device The output device to use * @param component The component to render * @param useTable true if it should be wrapped into a TABLE element (recommended!) or a DIV * @param optionalAttributes A map of additional CSS attributes * @throws IOException on error on the output device */ protected final void writePrefix(final Device device, final COMPONENT_TYPE component, final boolean useTable, Map optionalAttributes) throws IOException { // This is the containing element of a component // it is responsible for styles, sizing... if (useTable) { device.print("'); // table } else { device.print('>'); // div } } protected final void writeSuffix(Device device, COMPONENT_TYPE component, boolean useTable) throws IOException { if (useTable) { device.print(""); } else { device.print("
"); } } /** * Write JS code for context menus. Common implementaton for MSIE and gecko. * @deprecated use {@link Utils#writeContextMenu(Device, SComponent)} */ protected static void writeContextMenu(Device device, SComponent component) throws IOException { Utils.writeContextMenu(device, component); } /** * Write Tooltip code. * @deprecated use {@link Utils#writeTooltipMouseOver(Device, SComponent)} */ protected static void writeTooltipMouseOver(Device device, SComponent component) throws IOException { Utils.writeTooltipMouseOver(device, component); } /** * Install the appropriate CG for component. * * @param component the component */ @Override public void installCG(COMPONENT_TYPE component) { Class clazz = component.getClass(); while (clazz.getPackage() == null || !("org.wings".equals(clazz.getPackage().getName()) || "org.wingx".equals(clazz.getPackage().getName()))) clazz = clazz.getSuperclass(); String style = clazz.getName(); style = style.substring(style.lastIndexOf('.') + 1); component.setStyle(style); // set default style name to component class (ie. SLabel). component.setBorder(SDefaultBorder.INSTANCE); // the default style writes _no_ attributes, thus the stylesheet is in effect if (Utils.isMSIE(component)) { final CGManager manager = component.getSession().getCGManager(); Object value = manager.getObject(style + ".verticalOversize", Integer.class); int verticalOversize = 0; if (value != null) verticalOversize = (Integer) value; value = manager.getObject(style + ".horizontalOversize", Integer.class); int horizontalOversize = 0; if (value != null) horizontalOversize = (Integer) value; if (verticalOversize != 0 || horizontalOversize != 0) component.putClientProperty("oversize", new SEmptyBorder(verticalOversize, horizontalOversize, verticalOversize, horizontalOversize)); } } /** * Uninstall the CG from component. * * @param component the component */ @Override public void uninstallCG(COMPONENT_TYPE component) { } /** * Retrieve a empty blind icon. * @return A empty blind icon. */ protected static SIcon getBlindIcon() { return BLIND_ICON; } /** * This method renders the component (and all of its subcomponents) to the given device. */ @Override public void write(final Device device, final COMPONENT_TYPE component) throws IOException { Utils.printDebug(device, ""); component.fireRenderEvent(SComponent.START_RENDERING); try { org.wings.border.SBorder border = component.getBorder(); if ( border != null ) { border.getCG().writeComponentBorderPrefix(device, component); } writeInternal(device, component); ScriptManager.getInstance().addScriptListeners(component.getScriptListeners()); if ( border != null ) { border.getCG().writeComponentBorderSufix(device, component); } } catch (RuntimeException e) { log.error("Runtime exception during rendering of " + component.getName(), e); device.print("" + e.getClass().getName() + " during code generation of " + component.getName() + '(' + component.getClass().getName() + ")\n"); } component.fireRenderEvent(SComponent.DONE_RENDERING); Utils.printDebug(device, ""); updateDragAndDrop(component); } protected void updateDragAndDrop(final SComponent component) { if (component instanceof DragSource && ((DragSource)component).isDragEnabled()) { StringBuilder builder = STRING_BUILDER.get(); builder.setLength(0); String name = component.getName(); builder.append("var ds_"); builder.append(name); builder.append(" = new wingS.dnd.DD(\""); builder.append(name); builder.append("\");"); writeRegisterDragHandle(builder, component); builder.append('\n'); ScriptManager.getInstance().addScriptListener(new OnPageRenderedScript(builder.toString())); } if (component instanceof DropTarget) { StringBuilder builder = STRING_BUILDER.get(); builder.setLength(0); String name = component.getName(); builder.append("var dt_"); builder.append(name); builder.append(" = new YAHOO.util.DDTarget(\""); builder.append(name); builder.append("\");\n"); ScriptManager.getInstance().addScriptListener(new OnPageRenderedScript(builder.toString())); } } protected void writeRegisterDragHandle(StringBuilder builder, SComponent component) { String dragHandle = getDragHandle(component); if (dragHandle != null) { String name = component.getName(); builder.append("ds_"); builder.append(name); builder.append(".setHandleElId(\""); builder.append(dragHandle); builder.append("\");"); } } protected String getDragHandle(SComponent component) { return null; } public abstract void writeInternal(Device device, COMPONENT_TYPE component) throws IOException; @Override public Update getComponentUpdate(COMPONENT_TYPE component) { updateDragAndDrop(component); return new ComponentUpdate<>(this, component); } protected static class ComponentUpdate extends AbstractUpdate { private final AbstractComponentCG cg; public ComponentUpdate(AbstractComponentCG cg, COMPONENT_TYPE component) { super(component); this.cg = cg; } @Override public int getProperty() { return FULL_REPLACE_UPDATE; } @Override public int getPriority() { return 4; } @Override public Handler getHandler() { String htmlCode = ""; String exception = null; try { StringBuilderDevice htmlDevice = new StringBuilderDevice(1024); cg.write(htmlDevice, component); htmlCode = htmlDevice.toString(); } catch (Throwable t) { log.error("An error occured during rendering", t); exception = t.getClass().getName(); } UpdateHandler handler = new UpdateHandler("component"); handler.addParameter(component.getName()); handler.addParameter(htmlCode); if (exception != null) { handler.addParameter(exception); } return handler; } } }



© 2015 - 2024 Weber Informatics LLC | Privacy Policy