001    /*
002     * This file is part of the Echo Point Project.  This project is a
003     * collection of Components that have extended the Echo Web Application
004     * Framework Version 3.
005     *
006     * Version: MPL 1.1
007     *
008     * The contents of this file are subject to the Mozilla Public License Version
009     * 1.1 (the "License"); you may not use this file except in compliance with
010     * the License. You may obtain a copy of the License at
011     * http://www.mozilla.org/MPL/
012     *
013     * Software distributed under the License is distributed on an "AS IS" basis,
014     * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
015     * for the specific language governing rights and limitations under the
016     * License.
017     */
018    
019    package echopoint;
020    
021    import echopoint.internal.AbstractHtmlComponent;
022    import nextapp.echo.app.Component;
023    
024    import java.io.BufferedReader;
025    import java.io.IOException;
026    import java.io.InputStream;
027    import java.io.InputStreamReader;
028    
029    /**
030     * A container component that uses user specified XHTML layout to render
031     * components.  Provides a more flexible and powerful alternative to
032     * usual layout containers.
033     *
034     * <p>The following code shows sample use of this component:</p>
035     * <pre>
036     *  import echopoint.HtmlLayout;
037     *  import echopoint.layout.HtmlLayoutData;
038     *  import nextapp.echo.app.Button;
039     *  import nextapp.echo.app.Component;
040     *  import nextapp.echo.app.Label;
041     *
042     *    ...
043     *    final String text = "&lt;table border='1'&gt;" +
044     *        "&lt;tr&gt;" +
045     *        "&lt;td colspan='2'&gt;" +
046     *        "This is regular HTML text in layout component!" +
047     *        "&lt;/td&gt;" +
048     *        "&lt;/tr&gt;" +
049     *        "&lt;tr&gt;" +
050     *         "&lt;td id='one' colspan='2'&gt;&lt;/td&gt;" +
051     *         "&lt;/tr&gt;" +
052     *         "&lt;tr&gt;" +
053     *         "&lt;td id='two'&gt;&lt;/td&gt;" +
054     *         "&lt;td id='three'&gt;&lt;/td&gt;" +
055     *         "&lt;/tr&gt;" +
056     *         "&lt;/table&gt;";
057     *    final HtmlLayout container = new HtmlLayout( text );
058     *    Component child = new Button( "Button One" );
059     *
060     *    // Layout data that specified that component is child of td with id one
061     *    HtmlLayoutData layout = new HtmlLayoutData( "one" );
062     *    child.setLayoutData( layout );
063     *    container.add( child );
064     *
065     *    child = new Label( "Label One" );
066     *    layout = new HtmlLayoutData( "two" );
067     *    child.setLayoutData( layout );
068     *    container.add( child );
069     *
070     *    child = new Label( "Label Two" );
071     *    layout = new HtmlLayoutData( "three" );
072     *    child.setLayoutData( layout );
073     *    container.add( child );
074     *    ...
075     *    parent.add( container );
076     *    ...
077     *    final HtmlLayout fromFile = new HtmlLayout( "/tmp/test.html", "UTF-8" );
078     * </pre>
079     *
080     * @author Simon Lei 2009-03-16
081     * @version $Id: HtmlLayout.java 152 2009-04-19 21:53:22Z sptrakesh $
082     * @since 3.0.0a11
083     */
084    public class HtmlLayout extends AbstractHtmlComponent
085    {
086      private static final long serialVersionUID = 1l;
087    
088      /**
089       * Default constructor.  Not particularly useful.  You must invoke
090       * {@link #setText} before the layout container is rendered to avoid a
091       * client-side exception.
092       */
093      public HtmlLayout() {}
094    
095      /**
096       * Create a new instance using the specified XHTML layout code.
097       *
098       * @param text The layout code to use to embed components.
099       */
100      public HtmlLayout( final String text )
101      {
102        super( text );
103      }
104    
105      /**
106       * Create a new instance using the XHTML layout data specified in the
107       * input stream (file or resource usually).
108       *
109       * @param instream The input stream from which to read the XHTML layout data.
110       * @param charset The character set to use to read the input stream.
111       * @throws IOException If errors are encountered while reading the
112       *   contents of the input stream.
113       */
114      public HtmlLayout( final InputStream instream, final String charset )
115          throws IOException
116      {
117        final BufferedReader reader =
118            new BufferedReader( new InputStreamReader( instream, charset ) );
119        final StringBuilder builder = new StringBuilder( 1024 );
120        String line;
121    
122        while ( ( line = reader.readLine() ) != null )
123        {
124          builder.append( line );
125        }
126    
127        setText( builder.toString() );
128      }
129    
130      /**
131       * Over-ridden to return {@code true} since this component allows children.
132       *
133       * @param component The component to check.
134       * @return Returns {@code true}.
135       */
136      @Override
137      public boolean isValidChild( final Component component )
138      {
139        return true;
140      }
141    
142      /** Over-ridden to make no-op. */
143      @Override
144      public void setTarget( final String target )
145      {
146        // no op
147      }
148    }