001    /*
002     * Copyright (C) 2010 eXo Platform SAS.
003     *
004     * This is free software; you can redistribute it and/or modify it
005     * under the terms of the GNU Lesser General Public License as
006     * published by the Free Software Foundation; either version 2.1 of
007     * the License, or (at your option) any later version.
008     *
009     * This software is distributed in the hope that it will be useful,
010     * but WITHOUT ANY WARRANTY; without even the implied warranty of
011     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012     * Lesser General Public License for more details.
013     *
014     * You should have received a copy of the GNU Lesser General Public
015     * License along with this software; if not, write to the Free
016     * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
017     * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
018     */
019    
020    package org.crsh.shell.ui;
021    
022    import groovy.util.BuilderSupport;
023    import org.crsh.text.Color;
024    import org.crsh.text.Decoration;
025    
026    import java.util.ArrayList;
027    import java.util.List;
028    import java.util.Map;
029    
030    /**
031     * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
032     * @version $Revision$
033     */
034    public class UIBuilder extends BuilderSupport {
035    
036      /** . */
037      private final List<Element> elements;
038    
039      public UIBuilder() {
040        this.elements = new ArrayList<Element>();
041      }
042    
043      public List<Element> getElements() {
044        return elements;
045      }
046    
047      @Override
048      protected Object createNode(Object name) {
049        return createNode(name, (Object)null);
050      }
051    
052      @Override
053      protected Object createNode(Object name, Object value) {
054    
055        return initElement(name, value);
056    
057      }
058    
059      @Override
060      protected Object createNode(Object name, Map attributes, Object value) {
061        throw new UnsupportedOperationException();
062      }
063    
064      @Override
065      protected Object createNode(Object name, Map attributes) {
066    
067        Element e = initElement(name, attributes.get("value"));
068        setStyles(e, attributes);
069        Boolean border = (Boolean) attributes.get("border");
070        if (e instanceof TableElement) {
071          ((TableElement) e).setBorder(border == null ? false : border);
072        }
073        return e;
074        
075      }
076    
077      private Element initElement(Object name, Object value) {
078    
079        if ("node".equals(name)) {
080          if (value == null) {
081            return new TreeElement();
082          } else {
083            return new TreeElement(new LabelElement(value));
084          }
085        } else if ("label".equals(name)) {
086          return new LabelElement(value);
087        } else if ("table".equals(name)) {
088          return new TableElement();
089        } else if ("row".equals(name)) {
090          return new RowElement();
091        } else if ("header".equals(name)) {
092          return new RowElement(true);
093        } else {
094          throw new UnsupportedOperationException("Cannot build object with name " + name + " and value " + value);
095        }
096    
097      }
098      
099      private void setStyles(Element e, Map attributes) {
100        e.setDecoration((Decoration) attributes.get("decoration"));
101        e.setForeground((Color) attributes.get("foreground"));
102        e.setBackground((Color) attributes.get("background"));
103      }
104    
105      @Override
106      protected void setParent(Object parent, Object child) {
107        if (parent instanceof TreeElement) {
108          TreeElement parentElement = (TreeElement)parent;
109          Element childElement = (Element)child;
110          parentElement.addNode(childElement);
111          childElement.setParent(parentElement);
112        } else if (parent instanceof TableElement) {
113          TableElement parentElement = (TableElement)parent;
114          RowElement childElement = (RowElement)child;
115          parentElement.addRow(childElement);
116          childElement.setParent(parentElement);
117        } else if (parent instanceof RowElement) {
118          RowElement parentElement = (RowElement)parent;
119          Element childElement = (Element)child;
120          if (child instanceof TreeElement) {
121            throw new IllegalArgumentException("A table cannot contain node element");
122          }
123          parentElement.addValue(childElement);
124          childElement.setParent(parentElement);
125        } else {
126          throw new UnsupportedOperationException();
127        }
128      }
129    
130      @Override
131      protected void nodeCompleted(Object parent, Object child) {
132        if (parent == null) {
133          elements.add((Element)child);
134        }
135        super.nodeCompleted(parent, child);
136      }
137    }