/*
* Copyright (C) 2011 eXo Platform SAS.
*
* This 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 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.exoplatform.web.controller.router;
import org.exoplatform.web.url.MimeType;
import java.io.IOException;
import java.util.EnumMap;
import java.util.Map;
/**
* An uri writer.
*
* @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
*/
public final class URIWriter
{
/** . */
private static final Map<MimeType, String> AMP_MAP = new EnumMap<MimeType, String>(MimeType.class);
static
{
AMP_MAP.put(MimeType.XHTML, "&");
AMP_MAP.put(MimeType.PLAIN, "&");
}
/** . */
private MimeType mimeType;
/** . */
private Appendable appendable;
/** . */
private boolean questionMarkDone;
/** . */
private String amp;
/**
* Create a new URI writer.
*
* @param appendable the appendable
* @param mimeType the mime type
* @throws NullPointerException if the appendable argument is null
*/
public URIWriter(Appendable appendable, MimeType mimeType) throws NullPointerException
{
if (appendable == null)
{
throw new NullPointerException("No null appendable accepted");
}
//
this.appendable = appendable;
this.mimeType = mimeType;
}
/**
* Create a new URI writer.
*
* @param appendable the appendable
* @throws NullPointerException if the appendable argument is null
*/
public URIWriter(Appendable appendable) throws NullPointerException
{
this(appendable, null);
}
public MimeType getMimeType()
{
return mimeType;
}
public void setMimeType(MimeType mimeType)
{
this.mimeType = mimeType;
}
public void append(char c) throws IOException
{
appendable.append(c);
}
public void append(String s) throws IOException
{
appendable.append(s);
}
/**
* Append a segment to the path.
*
* @param c the char to append
* @throws IllegalStateException if a query parameter was already appended
* @throws IOException any IO exception
*/
public void appendSegment(char c) throws IllegalStateException, IOException
{
if (questionMarkDone)
{
throw new IllegalStateException("Query separator already written");
}
PercentEncoding.PATH_SEGMENT.encode(c, appendable);
}
/**
* Append a segment to the path.
*
* @param s the string to append.
* @throws NullPointerException if any argument value is null
* @throws IllegalStateException if a query parameter was already appended
* @throws IOException any IO exception
*/
public void appendSegment(String s) throws NullPointerException, IllegalStateException, IOException
{
if (s == null)
{
throw new NullPointerException("No null path accepted");
}
for (int len = s.length(), i = 0;i < len;i++)
{
char c = s.charAt(i);
appendSegment(c);
}
}
/**
* Append a query parameter to the parameter set. Note that the query parameters are ordered
* and the sequence of call to this method should be honoured when an URL is generated. Note also that
* the same parameter name can be used multiple times.
*
* @param parameterName the parameter name
* @param paramaterValue the parameter value
* @throws NullPointerException if any argument value is null
* @throws IOException any IOException
*/
public void appendQueryParameter(String parameterName, String paramaterValue) throws NullPointerException, IOException
{
if (parameterName == null)
{
throw new NullPointerException("No null parameter name accepted");
}
if (paramaterValue == null)
{
throw new NullPointerException("No null parameter value accepted");
}
//
if (amp == null)
{
MimeType mt = mimeType;
if (mt == null)
{
mt = MimeType.XHTML;
}
amp = AMP_MAP.get(mt);
}
//
appendable.append(questionMarkDone ? amp : "?");
PercentEncoding.QUERY_PARAM.encode(parameterName, appendable);
appendable.append('=');
PercentEncoding.QUERY_PARAM.encode(paramaterValue, appendable);
questionMarkDone = true;
}
/**
* Reset the writer for reuse.
*
* @param appendable the used appendable
*/
public void reset(Appendable appendable)
{
this.appendable = appendable;
this.questionMarkDone = false;
}
}