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

org.nuiton.widget.XMLGridParseConstraints Maven / Gradle / Ivy

There is a newer version: 1.1.1
Show newest version
/**
 * *##% Graphical Widget
 * Copyright (C) 2004 - 2008 CodeLutin
 *
 * This program 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 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Lesser Public License for more details.
 *
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * . ##%*
 */
package org.nuiton.widget;

import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.Point;
import java.io.ByteArrayInputStream;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.xml.sax.Attributes;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;

/**
 * Parses a XML input (a string, for the time being) into a Map of pairs (name,
 * constraint)
 * 
 * This class uses Apache Crimsom as the SaxParser
 * 
 * @author Rafael Alvarez
 */
class XMLGridParseConstraints extends DefaultHandler {
    XMLReader xr;
    private int td;
    private int tr;
    private Map constraints;
    private Map styles;
    private GridBagConstraints constraint;
    private int cellpadding;
    private int cellspacing;
    int anchor;
    private static final int TOP = 0x0001;
    private static final int BOTTOM = 0x0010;
    private static final int LEFT = 0x0100;
    private static final int RIGHT = 0x1000;
    private static final int CENTER = 0x11111;
    private boolean styleMode = false;
    private String id;

    /**
     * permet de genere precisement la place de chaque td et de faire des
     * decalage si necessaire
     */
    private Map table;

    public XMLGridParseConstraints() throws SAXException {
        xr = XMLReaderFactory.createXMLReader();
        xr.setContentHandler(this);
        xr.setErrorHandler(new MyErrorHandler());
    }

    public Map parse(String s) throws SAXException {
        constraints = new HashMap();
        styles = new HashMap();
        try {
            xr.parse(new InputSource(new ByteArrayInputStream(s.getBytes())));
        } catch (IOException e) {
            e.printStackTrace();
        }

        return constraints;
    }

    private CharArrayWriter contents = new CharArrayWriter();

    public void characters(char[] ch, int start, int length)
            throws SAXException {
        contents.write(ch, start, length);
    }

    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        if (localName.equals("td")) {
            handleOpenTD(attributes);
        } else if (localName.equals("table")) {
            handleOpenTable(attributes);
        } else if (localName.equals("style")) {
            handleOpenStyle(attributes);
        } else if (localName.equals("styles")) {
            handleOpenStyles();
        }
    }

    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        if (localName.equals("td")) {
            handleCloseTD();
        } else if (localName.equals("tr")) {
            this.td = 0;
            this.tr++;
        } else if (localName.equals("table")) {
            handleCloseTable();
        } else if (localName.equals("style")) {
            handleCloseTD();
        } else if (localName.equals("styles")) {
            handleCloseStyles();
        }
    }

    private void handleOpenStyles() {
        this.styleMode = true;
    }

    private void handleCloseStyles() {
        this.styleMode = false;
    }

    private void handleOpenTable(Attributes attributes) {
        table = new HashMap();
        for (int i = 0; i < attributes.getLength(); i++) {
            String name = attributes.getLocalName(i);
            String value = attributes.getValue(i);

            if (name.equals("cellpadding")) {
                cellpadding = Integer.parseInt(value); // CHECK for parse
                                                       // exception
            } else if (name.equals("cellspacing")) {
                cellspacing = Integer.parseInt(value); // CHECK for parse
                                                       // exception
            }
        }
    }

    private void handleCloseTable() {
        cellpadding = -1;
        cellspacing = -1;
    }

    private void handleOpenStyle(Attributes attributes) {
        constraint = new GridBagConstraints();
        fillConstraint(attributes);
    }

    private void handleOpenTD(Attributes attributes) {

        String tdStyle = attributes.getValue("", "class");
        GridBagConstraints constraintStyle = null;

        if (tdStyle != null) {
            constraintStyle = styles.get(tdStyle);
        }

        if (constraintStyle != null) {
            constraint = (GridBagConstraints) constraintStyle.clone();
        } else {
            constraint = new GridBagConstraints();
        }

        fillConstraint(attributes);

        // this.td += constraint.gridwidth;
    }

    private void fillConstraint(Attributes attributes) {
        constraint.gridx = this.td;
        constraint.gridy = this.tr;
        constraint.ipadx = cellpadding;
        constraint.ipady = cellpadding;
        constraint.insets = new Insets(cellspacing, cellspacing, cellspacing,
                cellspacing);

        contents.reset();

        int colspan = constraint.gridwidth;
        int rowspan = constraint.gridheight;

        for (int i = 0; i < attributes.getLength(); i++) {
            String name = attributes.getLocalName(i);
            String value = attributes.getValue(i);

            if (name.equals("colspan")) {
                colspan = Integer.parseInt(value); // CHECK for parse exception
            } else if (name.equals("rowspan")) {
                rowspan = Integer.parseInt(value); // CHECK for parse exception
            } else if (name.equals("fill")) {
                if (value.equalsIgnoreCase("BOTH")) {
                    constraint.fill = GridBagConstraints.BOTH;
                } else if (value.equalsIgnoreCase("HORIZONTAL")) {
                    constraint.fill = GridBagConstraints.HORIZONTAL;
                } else if (value.equalsIgnoreCase("VERTICAL")) {
                    constraint.fill = GridBagConstraints.VERTICAL;
                } else if (value.equalsIgnoreCase("NONE")) {
                    constraint.fill = GridBagConstraints.NONE;
                }
            } else if (name.equals("valign")) {
                if (value.equalsIgnoreCase("TOP")) {
                    anchor = anchor | TOP;
                } else if (value.equalsIgnoreCase("BOTTOM")) {
                    anchor = anchor | BOTTOM;
                } else if (value.equalsIgnoreCase("MIDDLE")) {
                    anchor = anchor | CENTER;
                }
            } else if (name.equals("align")) {
                if (value.equalsIgnoreCase("LEFT")) {
                    anchor = anchor | LEFT;
                } else if (value.equalsIgnoreCase("RIGHT")) {
                    anchor = anchor | RIGHT;
                } else if (value.equalsIgnoreCase("CENTER")) {
                    anchor = anchor | CENTER;
                }
            } else if (name.equals("width")) {
                constraint.weightx = Double.parseDouble(value.substring(0,
                        value.length() - 1)) / 100;
            } else if (name.equals("height")) {
                constraint.weighty = Double.parseDouble(value.substring(0,
                        value.length() - 1)) / 100;
            } else if (name.equals("id")) {
                this.id = value;
            }
        }

        constraint.gridwidth = colspan;
        constraint.gridheight = rowspan;

        if (!this.styleMode) {
            // looking for first empty slot in table
            Point p = new Point(constraint.gridx, constraint.gridy);
            GridBagConstraints old = table.get(p);
            while (old != null) {
                p.translate(1, 0);
                old = table.get(p);
            }
            constraint.gridx = (int) p.getX();
            constraint.gridy = (int) p.getY();

            // mark all used slot by this contrains in table map
            for (int x = 0; x < colspan; x++) {
                for (int y = 0; y < rowspan; y++) {
                    Point newPoint = p.getLocation();
                    newPoint.translate(x, y);
                    table.put(newPoint, constraint);
                }
            }
        }
    }

    private void handleCloseTD() {
        switch (anchor) {
        case LEFT:
            constraint.anchor = GridBagConstraints.WEST;
            break;
        case RIGHT:
            constraint.anchor = GridBagConstraints.EAST;
            break;
        case CENTER:
            constraint.anchor = GridBagConstraints.CENTER;
            break;
        case TOP:
            constraint.anchor = GridBagConstraints.NORTH;
            break;
        case BOTTOM:
            constraint.anchor = GridBagConstraints.SOUTH;
            break;
        case TOP | LEFT:
            constraint.anchor = GridBagConstraints.NORTHWEST;
            break;
        case TOP | RIGHT:
            constraint.anchor = GridBagConstraints.NORTHEAST;
            break;
        case BOTTOM | LEFT:
            constraint.anchor = GridBagConstraints.SOUTHWEST;
            break;
        case BOTTOM | RIGHT:
            constraint.anchor = GridBagConstraints.SOUTHEAST;
            break;
        }
        if (this.styleMode) {
            styles.put(this.id, constraint);
        } else {
            constraints.put(contents.toString().trim(), constraint);
        }
        contents.reset();
        anchor = 0;
    }

    public String getErrors() {
        MyErrorHandler errorHandler = (MyErrorHandler) xr.getErrorHandler();
        return errorHandler.getErrors();
    }

    public Map getStyles() {
        return Collections.unmodifiableMap(this.styles);
    }

    class MyErrorHandler implements ErrorHandler {
        StringBuffer errors = new StringBuffer();

        public void error(SAXParseException e) throws SAXException {
            errors.append(e.getMessage()).append("\n");
        }

        public void fatalError(SAXParseException e) throws SAXException {
            errors.append(e.getMessage()).append("\n");
        }

        public void warning(SAXParseException e) throws SAXException {
            errors.append(e.getMessage()).append(Character.LINE_SEPARATOR);
        }

        public String getErrors() {
            return errors.toString();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy