com.github.sviperll.text.Layout Maven / Gradle / Ivy
/*
* Copyright (c) 2015, Victor Nazarov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.github.sviperll.text;
import com.github.sviperll.Applicable;
/**
* Can be used as layout.
*
* {@code Layout<Html> } is supposed to generate
* html output.
*
* @param marks given renderable with it's format
*
* @author Victor Nazarov <[email protected]>
*/
public class Layout implements Layoutable {
@SuppressWarnings({"rawtypes", "unchecked"})
private static final Layout CHROMELESS = new Layout(new ChromelessLayoutable());
@SuppressWarnings("unchecked")
public static Layout chromeless() {
return CHROMELESS;
}
public static Layout of(Layoutable layoutable) {
if (layoutable instanceof Layout)
return (Layout)layoutable;
else
return new Layout(layoutable);
}
public static Layout of(Applicable header, Applicable footer) {
return new Layout(new FunctionLayoutable(header, footer));
}
private final Layoutable layoutable;
private Layout(Layoutable layoutable) {
this.layoutable = layoutable;
}
@Override
public Renderer createHeaderRenderer(Appendable appendable) {
return layoutable.createHeaderRenderer(appendable);
}
@Override
public Renderer createFooterRenderer(Appendable appendable) {
return layoutable.createFooterRenderer(appendable);
}
public Layout enclose(Layoutable thatLayoutable) {
return new Layout(new EnclosedLayoutable(this.layoutable, thatLayoutable));
}
private static class FunctionLayoutable implements Layoutable {
private final Applicable header;
private final Applicable footer;
public FunctionLayoutable(Applicable header, Applicable footer) {
this.header = header;
this.footer = footer;
}
@Override
public Renderer createHeaderRenderer(Appendable appendable) {
return header.apply(appendable);
}
@Override
public Renderer createFooterRenderer(Appendable appendable) {
return footer.apply(appendable);
}
}
private static class ChromelessLayoutable implements Layoutable {
@Override
public Renderer createHeaderRenderer(Appendable appendable) {
return Renderer.blank();
}
@Override
public Renderer createFooterRenderer(Appendable appendable) {
return Renderer.blank();
}
}
private static class EnclosedLayoutable implements Layoutable {
private final Layoutable enclosing;
private final Layoutable enclosed;
public EnclosedLayoutable(Layoutable enclosing, Layoutable enclosed) {
this.enclosing = enclosing;
this.enclosed = enclosed;
}
@Override
public Renderer createHeaderRenderer(Appendable appendable) {
return enclosing.createHeaderRenderer(appendable).andThen(enclosed.createHeaderRenderer(appendable));
}
@Override
public Renderer createFooterRenderer(Appendable appendable) {
return enclosed.createHeaderRenderer(appendable).andThen(enclosing.createHeaderRenderer(appendable));
}
}
}