001package org.apache.maven.doxia.sink.impl;
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 javax.swing.text.MutableAttributeSet;
023import javax.swing.text.html.HTML.Tag;
024
025import org.apache.maven.doxia.markup.XmlMarkup;
026
027/**
028 * An abstract <code>Sink</code> for xml markup syntax.
029 *
030 * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
031 * @version $Id$
032 * @since 1.0
033 */
034public abstract class AbstractXmlSink
035    extends SinkAdapter
036    implements XmlMarkup
037{
038    /** Default namespace prepended to all tags */
039    private String nameSpace;
040
041    private boolean firstTag  = true;
042
043    private boolean insertNewline = true;
044
045    public void setInsertNewline( boolean insertNewline )
046    {
047        this.insertNewline = insertNewline;
048    }
049
050    /**
051     * Sets the default namespace that is prepended to all tags written by this sink.
052     *
053     * @param ns the default namespace.
054     * @since 1.1
055     */
056    public void setNameSpace( String ns )
057    {
058        this.nameSpace = ns;
059    }
060
061    /**
062     * Return the default namespace that is prepended to all tags written by this sink.
063     *
064     * @return the current default namespace.
065     * @since 1.1
066     */
067    public String getNameSpace()
068    {
069        return this.nameSpace;
070    }
071
072    /**
073     * Starts a Tag. For instance:
074     * <pre>
075     * &lt;tag&gt;
076     * </pre>
077     *
078     * @param t a non null tag
079     * @see #writeStartTag(javax.swing.text.html.HTML.Tag, javax.swing.text.MutableAttributeSet)
080     */
081    protected void writeStartTag( Tag t )
082    {
083        writeStartTag ( t, null );
084    }
085
086    /**
087     * Starts a Tag with attributes. For instance:
088     * <pre>
089     * &lt;tag attName="attValue"&gt;
090     * </pre>
091     *
092     * @param t a non null tag.
093     * @param att a set of attributes. May be null.
094     * @see #writeStartTag(javax.swing.text.html.HTML.Tag, javax.swing.text.MutableAttributeSet, boolean).
095     */
096    protected void writeStartTag( Tag t, MutableAttributeSet att )
097    {
098        writeStartTag ( t, att, false );
099    }
100
101    /**
102     * Starts a Tag with attributes. For instance:
103     * <pre>
104     * &lt;tag attName="attValue"&gt;
105     * </pre>
106     *
107     * @param t a non null tag.
108     * @param att a set of attributes. May be null.
109     * @param isSimpleTag boolean to write as a simple tag.
110     */
111    protected void writeStartTag( Tag t, MutableAttributeSet att, boolean isSimpleTag )
112    {
113        if ( t == null )
114        {
115            throw new IllegalArgumentException( "A tag is required" );
116        }
117
118        StringBuilder sb = new StringBuilder();
119
120        if ( insertNewline && t.isBlock() && !firstTag )
121        {
122            sb.append( EOL );
123        }
124        firstTag = false;
125
126        sb.append( LESS_THAN );
127
128        if ( nameSpace != null )
129        {
130            sb.append( nameSpace ).append( ':' );
131        }
132
133        sb.append( t.toString() );
134
135        sb.append( SinkUtils.getAttributeString( att ) );
136
137        if ( isSimpleTag )
138        {
139            sb.append( SPACE ).append( SLASH );
140        }
141
142        sb.append( GREATER_THAN );
143
144        write( sb.toString() );
145    }
146
147    /**
148     * Writes a system EOL.
149     *
150     * @since 1.1
151     */
152    protected void writeEOL()
153    {
154        write( EOL );
155    }
156
157    /**
158     * Ends a Tag without writing an EOL. For instance: <pre>&lt;/tag&gt;</pre>.
159     *
160     * @param t a tag.
161     */
162    protected void writeEndTag( Tag t )
163    {
164        if ( t == null )
165        {
166            throw new IllegalArgumentException( "A tag is required" );
167        }
168
169        StringBuilder sb = new StringBuilder();
170        sb.append( LESS_THAN );
171        sb.append( SLASH );
172
173        if ( nameSpace != null )
174        {
175            sb.append( nameSpace ).append( ':' );
176        }
177
178        sb.append( t.toString() );
179        sb.append( GREATER_THAN );
180
181        write( sb.toString() );
182    }
183
184    /**
185     * Starts a simple Tag. For instance:
186     * <pre>
187     * &lt;tag /&gt;
188     * </pre>
189     *
190     * @param t a non null tag
191     * @see #writeSimpleTag(javax.swing.text.html.HTML.Tag, javax.swing.text.MutableAttributeSet)
192     */
193    protected void writeSimpleTag( Tag t )
194    {
195        writeSimpleTag( t, null );
196    }
197
198    /**
199     * Starts a simple Tag with attributes. For instance:
200     * <pre>
201     * &lt;tag attName="attValue" /&gt;
202     * </pre>
203     *
204     * @param t a non null tag.
205     * @param att a set of attributes. May be null.
206     * @see #writeStartTag(javax.swing.text.html.HTML.Tag, javax.swing.text.MutableAttributeSet, boolean).
207     */
208    protected void writeSimpleTag( Tag t, MutableAttributeSet att )
209    {
210        writeStartTag ( t, att, true );
211    }
212
213    /**
214     * Write a text to the sink.
215     *
216     * @param text the given text to write
217     */
218    protected abstract void write( String text );
219}