com.astamuse.asta4d.render.Renderer Maven / Gradle / Ivy
Show all versions of asta4d-core Show documentation
/*
* Copyright 2012 astamuse company,Ltd.
*
* 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 com.astamuse.asta4d.render;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import org.jsoup.nodes.Element;
import com.astamuse.asta4d.Configuration;
import com.astamuse.asta4d.Context;
import com.astamuse.asta4d.data.DataConvertor;
import com.astamuse.asta4d.data.concurrent.ParallelDataConvertor;
import com.astamuse.asta4d.render.transformer.ElementSetterTransformer;
import com.astamuse.asta4d.render.transformer.ElementTransformer;
import com.astamuse.asta4d.render.transformer.RendererTransformer;
import com.astamuse.asta4d.render.transformer.Transformer;
import com.astamuse.asta4d.render.transformer.TransformerFactory;
import com.astamuse.asta4d.util.collection.ListConvertUtil;
import com.astamuse.asta4d.util.collection.ParallelRowConvertor;
import com.astamuse.asta4d.util.collection.RowConvertor;
/**
* A renderer is for describing rendering actions.
*
* Developers usually do not need to create a Renderer by constructors directly,
* alternatively a renderer can be created by calling the static {@code create}
* methods or the {@code add} methods.
*
*
* @author e-ryu
*
*/
public class Renderer {
private final static boolean saveCallstackInfo;
static {
saveCallstackInfo = Configuration.getConfiguration().isSaveCallstackInfoOnRendererCreation();
}
private String selector;
private List> transformerList;
private List chain;
private String creationSiteInfo = null;
/**
* Create a Renderer by given css selector and {@link Transformer}
*
* @param selector
* a selector that describes the rendering target element
* @param transformer
* the action that describes how to render the target element
*/
public Renderer(String selector, Transformer> transformer) {
List> list = new ArrayList<>();
list.add(transformer);
init(selector, list);
}
/**
* Create a Renderer by given css selector and List of {@link Transformer}.
* By given a list, the target element will be duplicated to the same count
* of Transformer list size.
*
* @param selector
* a selector that describes the rendering target element
* @param transformerList
* the action list that describes how to render the target
* element
*/
public Renderer(String selector, List> transformerList) {
init(selector, transformerList);
}
private void init(String selector, List> transformerList) {
this.selector = selector;
this.transformerList = transformerList;
chain = new ArrayList<>();
chain.add(this);
if (saveCallstackInfo) {
StackTraceElement[] Stacks = Thread.currentThread().getStackTrace();
StackTraceElement callSite = null;
boolean myClsStarted = false;
for (StackTraceElement stackTraceElement : Stacks) {
if (stackTraceElement.getClassName().equals(Renderer.class.getName())) {
myClsStarted = true;
continue;
} else if (myClsStarted) {
callSite = stackTraceElement;
break;
}
}
if (callSite != null) {
creationSiteInfo = callSite.toString();
}
}
}
public String getSelector() {
return selector;
}
public List> getTransformerList() {
return transformerList;
}
@Override
public String toString() {
return "\n\"" + selector + "\"#>\n{" + this.transformerList + "}\n\n";
}
RendererType getRendererType() {
return RendererType.COMMON;
}
String getCreationSiteInfo() {
return creationSiteInfo;
}
/**
* Get list of all the renderers hold by the current renderer
*
* @return an unmodifiable list of renderers
*/
public List asUnmodifiableList() {
return Collections.unmodifiableList(new ArrayList<>(this.chain));
}
/**
* add a renderer to the current renderer as a list
*
* @param renderer
* a renderer
* @return the parameter renderer for chain calling
*/
public Renderer add(Renderer renderer) {
this.chain.addAll(renderer.chain);
for (Renderer r : renderer.chain) {
r.chain = this.chain;
}
return renderer;
}
/**
* See {@link #add(String, String)}.
*
* @param selector
* a css selector
* @param value
* a long value that will be treated as a String
* @return the created renderer for chain calling
*/
public Renderer add(String selector, Long value) {
return add(create(selector, value));
}
/**
* See {@link #add(String, String)}.
*
* @param selector
* a css selector
* @param value
* an int value that will be treated as a String
* @return the created renderer for chain calling
*/
public Renderer add(String selector, Integer value) {
return add(create(selector, value));
}
/**
* See {@link #add(String, String)}.
*
* @param selector
* a css selector
* @param value
* a boolean value that will be treated as a String
* @return the created renderer for chain calling
*/
public Renderer add(String selector, boolean value) {
return add(create(selector, value));
}
/**
* Create a renderer for text rendering by given parameter and add it to the
* current renderer. See {@link #create(String, String)}.
*
* @param selector
* a css selector
* @param value
* a String value that will be rendered
* @return the created renderer for chain calling
*/
public Renderer add(String selector, String value) {
return add(create(selector, value));
}
/**
* Create a renderer for text rendering by given parameter and add it to the
* current renderer. See {@link #create(String, Object)}.
*
* @param selector
* a css selector
* @param value
* a Object value that will be rendered
* @return the created renderer for chain calling
*/
public Renderer add(String selector, Object value) {
return add(create(selector, value));
}
/**
* See {@link #add(String, String, String)}.
*
* @param selector
* a css selector
* @param attr
* the attribute name to set
* @param value
* a long value that will be treated as a String value
* @return the created renderer for chain calling
*/
public Renderer add(String selector, String attr, long value) {
return add(create(selector, attr, value));
}
/**
* See {@link #add(String, String, String)}.
*
* @param selector
* a css selector
* @param attr
* the attribute name to set
* @param value
* an int value that will be treated as a String value
* @return the created renderer for chain calling
*/
public Renderer add(String selector, String attr, int value) {
return add(create(selector, attr, value));
}
/**
* See {@link #add(String, String, String)}.
*
* @param selector
* a css selector
* @param attr
* the attribute name to set
* @param value
* a boolean value that will be treated as a String value
* @return the created renderer for chain calling
*/
public Renderer add(String selector, String attr, boolean value) {
return add(create(selector, attr, value));
}
/**
* Create a renderer for attribute setting by given parameter and add it to
* the current renderer. See {@link #create(String, String, String)}.
*
* @param selector
* a css selector
* @param attr
* the attribute name to set
* @param value
* a String value that will be treated as the attribute value
* @return the created renderer for chain calling
*/
public Renderer add(String selector, String attr, String value) {
return add(create(selector, attr, value));
}
/**
* Create a renderer for attribute setting by given parameter and add it to
* the current renderer. See {@link #create(String, String, Object)}.
*
* @param selector
* a css selector
* @param attr
* the attribute name to set
* @param value
* a Object value that will be treated as the attribute value
* @return the created renderer for chain calling
*/
public Renderer add(String selector, String attr, Object value) {
return add(create(selector, attr, value));
}
/**
* Create a renderer for element rendering by given parameter and add it to
* the current renderer. See {@link #create(String, Element)}.
*
* @param selector
* a css selector
* @param elem
* a element that to be rendered
* @return the created renderer for chain calling
*/
public Renderer add(String selector, Element elem) {
return add(create(selector, elem));
}
/**
* Create a renderer for element setting by given parameter and add it to
* the current renderer. See {@link #create(String, ElementSetter)}.
*
* @param selector
* a css selector
* @param setter
* an ElementSetter
* @return the created renderer for chain calling
*/
public Renderer add(String selector, ElementSetter setter) {
return add(create(selector, setter));
}
/**
* Create a renderer for recursive renderer rendering by given parameter and
* add it to the current renderer. See {@link #create(String, Renderer)}.
*
* @param selector
* a css selector
* @param renderer
* a renderer
* @return the created renderer for chain calling
*/
public Renderer add(String selector, Renderer renderer) {
return add(create(selector, renderer));
}
/**
* Create a renderer for list rendering by given parameter and add it to the
* current renderer. See {@link #create(String, List)}.
*
* @param selector
* a css selector
* @param list
* a list that can contain all the types that supported by the
* non-list add methods of Renderer.
* @return the created renderer for chain calling
*/
public Renderer add(String selector, Iterable> list) {
return add(create(selector, list));
}
/**
* Create a renderer for list rendering by given parameter with given
* {@link RowConvertor} and add it to the current renderer. See
* {@link #create(String, List)}.
*
* @param selector
* @param list
* @param convertor
* @return the created renderer for chain calling
*/
public Renderer add(String selector, Iterable list, RowConvertor convertor) {
return add(create(selector, list, convertor));
}
/**
* Create a renderer for list rendering by given parameter with given
* {@link DataConvertor} and add it to the current renderer. See
* {@link #create(String, Iterable, ParallelRowConvertor)}.
*
* @param selector
* @param list
* @param convertor
* @return the created renderer for chain calling
*/
public Renderer add(String selector, Iterable list, ParallelRowConvertor convertor) {
return add(create(selector, list, convertor));
}
/**
* Create a renderer for list rendering by given parameter with given
* {@link DataConvertor} and add it to the current renderer. See
* {@link #create(String, List)}.
*
* This method has been deprecated. Use
* {@link #add(String, Iterable, RowConvertor)} instead.
*
* @param selector
* @param list
* @param convertor
* @return the created renderer for chain calling
*/
@Deprecated
public Renderer add(String selector, Iterable list, DataConvertor convertor) {
return add(create(selector, list, convertor));
}
/**
* Create a renderer for list rendering by given parameter with given
* {@link ParallelDataConvertor} and add it to the current renderer. See
* {@link #create(String, List)}.
*
* This method has been deprecated. Use
* {@link #add(String, Iterable, ParallelRowConvertor)} instead.
*
* @param selector
* @param list
* @param convertor
* @return the created renderer for chain calling
*/
@Deprecated
public Renderer add(String selector, Iterable list, ParallelDataConvertor convertor) {
return add(create(selector, list, convertor));
}
/**
* add a {@link DebugRenderer} to the current Renderer and when this
* renderer is applied, the target element specified by the given selector
* will be output by logger.
*
* @param selector
* a css selector
* @return the created renderer or the current renderer for chain calling
*/
public Renderer addDebugger(String logMessage, String selector) {
return DebugRenderer.logger.isDebugEnabled() ? add(create(selector, new DebugRenderer(logMessage))) : this;
}
/**
* add a {@link DebugRenderer} to the current Renderer and when this
* renderer is applied, the current rendering element (see
* {@link Context#setCurrentRenderingElement(Element)}) will be output by
* logger.
*
* @return the created renderer or the current renderer for chain calling
*/
public Renderer addDebugger(String logMessage) {
return DebugRenderer.logger.isDebugEnabled() ? add(new DebugRenderer(logMessage)) : this;
}
/**
* See {@link #create(String, String)}.
*
* @param selector
* a css selector
* @param value
* a long value that will be treated as a String
* @return the created renderer
*/
public final static Renderer create(String selector, Long value) {
return create(selector, String.valueOf(value));
}
/**
* See {@link #create(String, String)}.
*
* @param selector
* a css selector
* @param value
* an int value that will be treated as a String
* @return the created renderer
*/
public final static Renderer create(String selector, Integer value) {
return create(selector, String.valueOf(value));
}
/**
* See {@link #create(String, String)}.
*
* @param selector
* a css selector
* @param value
* a boolean value that will be treated as a String
* @return the created renderer
*/
public final static Renderer create(String selector, Boolean value) {
return create(selector, String.valueOf(value));
}
/**
* Create a renderer for text by given parameter.
*
* All child nodes of the target element specified by selector will be
* emptied and the given String value will be rendered as a single text node
* of the target element.
*
* @param selector
* a css selector
* @param value
* a String value that will be rendered
* @return the created renderer
*/
public final static Renderer create(String selector, String value) {
return create(selector, new TextSetter(value));
}
/**
* Create a renderer for text by given parameter.
*
* All child nodes of the target element specified by selector will be
* emptied and the given String value will be rendered as a single text node
* of the target element.
*
* @param selector
* a css selector
* @param value
* a Object that will be rendered. toString() will be called for
* generating a String
* @return the created renderer
*/
public final static Renderer create(String selector, Object value) {
String s = value == null ? null : value.toString();
return create(selector, new TextSetter(s));
}
/**
* See {@link #create(String, String, String)}.
*
* @param selector
* a css selector
* @param attr
* the attribute name to set
* @param value
* a long value that will be treated as a String value
* @return the created renderer
*/
public final static Renderer create(String selector, String attr, long value) {
return create(selector, attr, String.valueOf(value));
}
/**
* See {@link #create(String, String, String)}.
*
* @param selector
* a css selector
* @param attr
* the attribute name to set
* @param value
* an int value that will be treated as a String value
* @return the created renderer
*/
public final static Renderer create(String selector, String attr, int value) {
return create(selector, attr, String.valueOf(value));
}
/**
* See {@link #create(String, String, String)}.
*
* @param selector
* a css selector
* @param attr
* the attribute name to set
* @param value
* a boolean value that will be treated as a String value
* @return the created renderer
*/
public final static Renderer create(String selector, String attr, boolean value) {
return create(selector, attr, String.valueOf(value));
}
/**
* Create a renderer for attribute setting by given parameter.
*
* An additional character of "+" or "-" can be used as a prefix of
* attribute name. See detail at {@link AttributeSetter}.
*
* @param selector
* a css selector
* @param attr
* the attribute name to set
* @param value
* a String value that will be treated as the attribute value
* @return the created renderer
*/
public final static Renderer create(String selector, String attr, String value) {
return create(selector, new AttributeSetter(attr, value));
}
/**
* Create a renderer for attribute setting by given parameter.
*
* An additional character of "+" or "-" can be used as a prefix of
* attribute name. There is also a special logic for an instance with
* arbitrary type. See detail at {@link AttributeSetter}.
*
* @param selector
* a css selector
* @param attr
* the attribute name to set
* @param value
* a Object value that will be treated as the attribute value
* @return the created renderer
*/
public final static Renderer create(String selector, String attr, Object value) {
return create(selector, new AttributeSetter(attr, value));
}
/**
* Create a renderer for element rendering by given parameter.
*
* The target element specified by the selector will be completely replaced
* by the given element.
*
* @param selector
* a css selector
* @param elem
* a element that to be rendered
* @return the created renderer
*/
public final static Renderer create(String selector, Element elem) {
return new Renderer(selector, new ElementTransformer(elem));
}
/**
* Create a renderer for element setting by given parameter.
*
* The target element specified by the given selector will not be replaced
* and will be passed to the given {@link ElementSetter} as a parameter.
*
* @param selector
* a css selector
* @param setter
* an ElementSetter
* @return the created renderer
*/
public final static Renderer create(String selector, ElementSetter setter) {
return new Renderer(selector, new ElementSetterTransformer(setter));
}
/**
* Create a renderer for recursive renderer rendering by given parameter.
*
* The given renderer will be applied to element specified by the given
* selector.
*
* @param selector
* a css selector
* @param renderer
* a renderer
* @return the created renderer for chain calling
*/
public final static Renderer create(String selector, Renderer renderer) {
return new Renderer(selector, new RendererTransformer(renderer));
}
/**
* Create a renderer for list rendering by given parameter.
*
* The target Element specified by the given selector will be duplicated
* times as the count of the given list and the contents of the list will be
* applied to the target Element too.
*
* @param selector
* a css selector
* @param list
* a list that can contain all the types supported by the
* non-list add methods of Renderer
* @return the created renderer
*/
public final static Renderer create(String selector, Iterable> list) {
List> transformerList = new LinkedList<>();
for (Object obj : list) {
transformerList.add(TransformerFactory.generateTransformer(obj));
}
return new Renderer(selector, transformerList);
}
/**
* Create a renderer for list rendering by given parameter with given
* {@link RowConvertor}. See {@link #create(String, List)}.
*
* @param selector
* a css selector
* @param list
* a list with arbitrary type data
* @param convertor
* a convertor that can convert the arbitrary types of the list
* data to the types supported by the non-list create methods of
* Renderer
* @return the created renderer
*/
public final static Renderer create(String selector, Iterable list, RowConvertor convertor) {
return create(selector, ListConvertUtil.transform(list, convertor));
}
/**
* Create a renderer for list rendering by given parameter with given
* {@link ParallelRowConvertor}. This method will not block the current
* thread and will return immediately.
*
* See {@link #create(String, List)}.
*
* @param selector
* a css selector
* @param list
* a list with arbitrary type data
* @param convertor
* a convertor that can convert the arbitrary types of the list
* data to the types supported by the non-list create methods of
* Renderer
* @return the created renderer
*/
public final static Renderer create(String selector, Iterable list, final ParallelRowConvertor convertor) {
if (Configuration.getConfiguration().isBlockParallelListRendering()) {
return create(selector, ListConvertUtil.transform(list, convertor));
} else {
return create(selector, ListConvertUtil.transformToFuture(list, convertor));
}
}
/**
* Create a renderer for list rendering by given parameter with given
* {@link DataConvertor}. See {@link #create(String, List)}.
*
* This method has been deprecated. Use
* {@link #create(String, Iterable, RowConvertor)} instead.
*
* @param selector
* a css selector
* @param list
* a list with arbitrary type data
* @param convertor
* a convertor that can convert the arbitrary types of the list
* data to the types supported by the non-list create methods of
* Renderer
* @return the created renderer
*/
@Deprecated
public final static Renderer create(String selector, Iterable list, DataConvertor convertor) {
return create(selector, ListConvertUtil.transform(list, convertor));
}
/**
* Create a renderer for list rendering by given parameter with given
* {@link ParallelDataConvertor}. This method will not block the current
* thread and will return immediately.
*
* See {@link #create(String, List)}.
*
* This method has been deprecated. Use
* {@link #create(String, Iterable, ParallelRowConvertor)} instead.
*
* @param selector
* a css selector
* @param list
* a list with arbitrary type data
* @param convertor
* a convertor that can convert the arbitrary types of the list
* data to the types supported by the non-list create methods of
* Renderer
* @return the created renderer
*/
@Deprecated
public final static Renderer create(String selector, Iterable list, final ParallelDataConvertor convertor) {
return create(selector, ListConvertUtil.transformToFuture(list, convertor));
}
// Render action control
public Renderer disableMissingSelectorWarning() {
return this.add(new RenderActionRenderer(RenderActionStyle.DISABLE_MISSING_SELECTOR_WARNING));
}
public Renderer eableMissingSelectorWarning() {
return this.add(new RenderActionRenderer(RenderActionStyle.ENABLE_MISSING_SELECTOR_WARNING));
}
}