001package org.apache.maven.doxia.module.twiki.parser;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.lang.reflect.Method;
023import java.util.Collections;
024
025import org.apache.maven.doxia.sink.Sink;
026
027/**
028 * Block that represents a section
029 *
030 * @author Juan F. Codagnone
031 * @version $Id$
032 */
033public class SectionBlock
034    extends AbstractFatherBlock
035{
036    /** {@inheritDoc} */
037    private final String title;
038
039    /** {@inheritDoc} */
040    private final int level;
041
042    /**
043     * Creates the SectionBlock.
044     * <p/>
045     * No parameter can be <code>null</code>
046     *
047     * @param title  the section title.
048     * @param level  the section level: 0 < level < 6
049     * @param blocks child blocks
050     */
051    public SectionBlock( final String title, final int level, final Block[] blocks )
052    {
053        super( blocks );
054        final int maxLevel = 5;
055        if ( title == null )
056        {
057            throw new IllegalArgumentException( "title cant be null" );
058        }
059        else if ( level < 1 || level > maxLevel )
060        {
061            throw new IllegalArgumentException( "invalid level: " + level );
062        }
063
064        this.title = title;
065        this.level = level;
066    }
067
068    /** {@inheritDoc} */
069    final void before( final Sink sink )
070    {
071        sectionStart( sink );
072        sectionTitle( sink );
073        sink.text( title );
074        sectionTitle_( sink );
075
076    }
077
078    /** {@inheritDoc} */
079    final void after( final Sink sink )
080    {
081        sectionEnd( sink );
082    }
083
084    /**
085     * call to sink.section<Level>()
086     *
087     * @param sink sink
088     */
089    private void sectionStart( final Sink sink )
090    {
091        invokeVoidVoid( sink, "section" + level );
092    }
093
094    /**
095     * call to sink.section<Level>_()
096     *
097     * @param sink sink
098     */
099    private void sectionEnd( final Sink sink )
100    {
101        invokeVoidVoid( sink, "section" + level + "_" );
102    }
103
104    /**
105     * Let you call sink's methods that returns <code>null</code> and have
106     * no parameters.
107     *
108     * @param sink the Sink
109     * @param name the name of the method to call
110     */
111    private void invokeVoidVoid( final Sink sink, final String name )
112    {
113        try
114        {
115            final Method m = sink.getClass().getMethod( name, new Class[] {} );
116            m.invoke( sink, Collections.EMPTY_LIST.toArray() );
117        }
118        catch ( Exception e )
119        {
120            // FIXME
121            throw new IllegalArgumentException( "invoking sink's " + name + " method: " + e.getMessage() );
122        }
123    }
124
125    /**
126     * Returns the level.
127     *
128     * @return <code>int</code> with the level.
129     */
130    public final int getLevel()
131    {
132        return level;
133    }
134
135    /**
136     * Returns the title.
137     *
138     * @return <code>String</code> with the title.
139     */
140    public final String getTitle()
141    {
142        return title;
143    }
144
145    /** {@inheritDoc} */
146    public final String toString()
147    {
148        final StringBuilder sb = new StringBuilder();
149
150        sb.append( "Section  {title: '" );
151        sb.append( getTitle() );
152        sb.append( "' level: " );
153        sb.append( getLevel() );
154        sb.append( "}: [" );
155        for ( int i = 0; i < getBlocks().length; i++ )
156        {
157            final Block block = getBlocks()[i];
158
159            sb.append( block.toString() );
160            sb.append( ", " );
161        }
162        sb.append( "]" );
163        return sb.toString();
164    }
165
166    /** @param sink */
167    private void sectionTitle( final Sink sink )
168    {
169        invokeVoidVoid( sink, "sectionTitle" + level );
170    }
171
172    /** @param sink */
173    private void sectionTitle_( final Sink sink )
174    {
175        invokeVoidVoid( sink, "sectionTitle" + level + "_" );
176    }
177}