All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cat.inspiracio.orange.Template Maven / Gradle / Ivy

/*    Copyright 2019 Alexander Bunkenburg

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
package cat.inspiracio.orange;

import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;

public abstract class Template {
	private static final String NL="\n";
	
	// state -----------------------------------------------
	//All these variables are visible in the write() method.
	//Like implicit objects in JSP 2.3. See spec in doc/.

	protected HttpServletRequest request;
	protected HttpServletResponse response;
	protected PageContext pageContext;
	protected HttpSession session;
	protected ServletContext application;
	protected JspWriter out;
	protected ServletConfig config;
	protected Template page;
	protected Throwable exception;

	// construction --------------------------------
	
	public Template(PageContext pc){
		out = pc.getOut();
		pageContext = pc;
		request = (HttpServletRequest)pc.getRequest();
		response = (HttpServletResponse)pc.getResponse();
		session = pc.getSession();
		application = pc.getServletContext();
		config = pc.getServletConfig();
		page = this;//Spec: "synonym for this", but with type Object.
		exception = (Throwable) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
	}

	// abstract method -----------------------------
	
	/** This is the method that template must implement. 
	 * @throws Exception Java-islands threw an exception. */
	public abstract void render() throws Exception;

	// orange logic ------------------------------

	/** Sends a temporary redirect response to the client using the specified
	 * redirect location URL. This method can accept relative URLs;
	 * the servlet container must convert the relative URL to an absolute URL
	 * before sending the response to the client. If the location is relative
	 * without a leading '/' the container interprets it as relative to the
	 * current request URI. If the location is relative with a leading '/' the
	 * container interprets it as relative to the servlet container root.
	 *
	 * If the response has already been committed, this method throws an
	 * IllegalStateException. After using this method, the response should be
	 * considered to be committed and should not be written to.
	 *
	 * After redirect, template execution continues. There will be no more
	 * output to the response, but maybe there are other effects.
	 * In order to avoid it, you can follow it by
	 *
	 * 	if(true) return;
	 *
	 * Uses status code 302.
	 *
	 * @param location the redirect location URL, can be relative
	 * @throws IOException If an input or output exception occurs
	 * @throws IllegalStateException If the response was committed or if a partial
	 * 	URL is given and cannot be converted into a valid URL
	 */
	protected void redirect(String location) throws IOException {
		response.sendRedirect(location);
	}

	/** Forward.
	 *
	 * After forward, template execution continues. There will be no more
	 * output to the response, but maybe there are other effects.
	 * In order to avoid it, you can follow it by
	 *
	 * 	if(true) return;
	 *
	 * @param u the forward location URL, can be relative
	 * @throws ServletException if the target resource throws this exception
	 * @throws IOException if the target resource throws this exception
	 * @throws IllegalStateException If the response was committed or if a partial
	 * 	URL is given and cannot be converted into a valid URL
	 */
	protected void forward(String u) throws ServletException, IOException {
		RequestDispatcher dispatcher = request.getRequestDispatcher(u);
		dispatcher.forward(request,response);
	}

	/** Quotes a value so that it can be an attribute's value.
     * Escapes " by " and encloses in ".
	 * For null returns quote("").
     * Called from generated write(). 
     * @param o object 
     * @return quoted */
    protected final String quote(Object o){
    	if(o==null)
    		return "\"\"";
    	String s = o.toString();
    	if(s==null)
    		return "\"\"";
		String value = unquote(s);
		//optimise: In html5, quotes are often not needed.
		return '"' + value + '"';
    }

    /** Escapes " by " .
	 * For null returns "".
	 * Called from generated write().
	 * @param o Object */
    protected final String unquote(Object o){
    	if(o==null)
    		return "";
    	String value = o.toString();
    	if(value==null)
    		return "";
		if(contains(value, '"'))
			value=value.replaceAll("\"", """);
		return value;
	}

	/** escape for html: ≤ & 
	 * Called from generated write(). 
	 * @param o Object
	 * @return escaped */
	protected final String escape(Object o){
		if(o==null)
			return "";
		String s = o.toString();
		if(s==null)
			return "";
		//Need to optimise?
		return s.replace("&", "&").replace("<", "<");
	}
	
	/** Escapes an int for html: just convert it to String.
	 * Called from generated write(). 
	 * @param i int
	 * @return escaped */
	protected final String escape(int i){return Integer.toString(i);}
	
	/** Boolean attribute: write the key if the value is true.
	 * Called from generated write(). 
	 * @param key key
	 * @param b value 
	 * @throws IOException couldn't write */
    protected final void attribute(String key, boolean b) throws IOException{
    	if(b)write(" " + key);
    }
    
    /** Attribute: 
     * If the value is empty, writes just the key,
     * otherwise key and value, quoted. 
     * @param key key
     * @param v value
     * @throws IOException bad IO 
     * */
    protected final void attribute(String key, Object v) throws IOException{
    	if(v==null){
    		write(" " + key);
    		return;
    	}
    	String s = v.toString();
    	if(empty(s)){
    		write(" " + key);
    		return;
    	}
    	write(" " + key + "=" + quote(s));
    }
    
    private final boolean empty(String s){return s==null || 0==s.length();}
    
    /** Does the string contain this character? */
    private final boolean contains(String value, char c){return 0<=value.indexOf(c);}
    
    // writing -------------------------------------
	
    /** Writes an int to out. 
     * Called from generated write(). */
	public final Template write(int i)throws IOException{
		out.write(Integer.toString(i));
		return this;
	}
	
    /** Writes an object to out.
     * Does nothing if the object is empty (null or its toString() is null or ""). */
	public final Template write(Object o)throws IOException{
		if(o==null)
			return this;
		String s = o.toString();
		return write(s);
	}
	
    /** Writes a String to out.
     * Does nothing if the String is null or "". */
	public final Template write(String s)throws IOException{
		if(!empty(s))
			out.write(s);
		return this;
	}
	
	/** Write a string to output. */
	public final Template writeln()throws IOException{return write(NL);}
	
	/** Write a string to output. */
	public final Template writeln(String s)throws IOException{
		write(s);
		return writeln();
	}
		
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy