강력 한 패 키 징 태그 패 키 징 클래스
6269 단어 자바
import java.io.IOException;
import java.io.Writer;
import java.util.Stack;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import net.favornet.common.Helper;
public class TagWriter {
/**
* The {@link SafeWriter} to write to.
*/
private final SafeWriter writer;
/**
* Stores {@link TagStateEntry tag state}. Stack model naturally supports tag nesting.
*/
private final Stack<TagStateEntry> tagState = new Stack<TagStateEntry>();
/**
* Create a new instance of the {@link TagWriter} class that writes to
* the supplied {@link PageContext}.
* @param pageContext the JSP PageContext to obtain the {@link Writer} from
*/
public TagWriter(PageContext pageContext) {
this.writer = new SafeWriter(pageContext);
}
/**
* Create a new instance of the {@link TagWriter} class that writes to
* the supplied {@link Writer}.
* @param writer the {@link Writer} to write tag content to
*/
public TagWriter(Writer writer) {
this.writer = new SafeWriter(writer);
}
/**
* Start a new tag with the supplied name. Leaves the tag open so
* that attributes, inner text or nested tags can be written into it.
* @see #endTag()
*/
public void startTag(String tagName) throws JspException {
if (inTag()) {
closeTagAndMarkAsBlock();
}
push(tagName);
this.writer.append("<").append(tagName);
}
/**
* Write an HTML attribute with the specified name and value.
* <p>Be sure to write all attributes <strong>before</strong> writing
* any inner text or nested tags.
* @throws IllegalStateException if the opening tag is closed
*/
public void writeAttribute(String attributeName, String attributeValue) throws JspException {
if (currentState().isBlockTag()) {
throw new IllegalStateException("Cannot write attributes after opening tag is closed.");
}
this.writer.append(" ").append(attributeName).append("=\"")
.append(attributeValue).append("\"");
}
/**
* Write an HTML attribute if the supplied value is not {@code null}
* or zero length.
* @see #writeAttribute(String, String)
*/
public void writeOptionalAttributeValue(String attributeName, String attributeValue) throws JspException {
if (!Helper.isNull(attributeValue)) {
writeAttribute(attributeName, attributeValue);
}
}
/**
* Close the current opening tag (if necessary) and appends the
* supplied value as inner text.
* @throws IllegalStateException if no tag is open
*/
public void appendValue(String value) throws JspException {
if (!inTag()) {
throw new IllegalStateException("Cannot write tag value. No open tag available.");
}
closeTagAndMarkAsBlock();
this.writer.append(value);
}
/**
* Indicate that the currently open tag should be closed and marked
* as a block level element.
* <p>Useful when you plan to write additional content in the body
* outside the context of the current {@link TagWriter}.
*/
public void forceBlock() throws JspException {
if (currentState().isBlockTag()) {
return; // just ignore since we are already in the block
}
closeTagAndMarkAsBlock();
}
/**
* Close the current tag.
* <p>Correctly writes an empty tag if no inner text or nested tags
* have been written.
*/
public void endTag() throws JspException {
endTag(false);
}
/**
* Close the current tag, allowing to enforce a full closing tag.
* <p>Correctly writes an empty tag if no inner text or nested tags
* have been written.
* @param enforceClosingTag whether a full closing tag should be
* rendered in any case, even in case of a non-block tag
*/
public void endTag(boolean enforceClosingTag) throws JspException {
if (!inTag()) {
throw new IllegalStateException("Cannot write end of tag. No open tag available.");
}
boolean renderClosingTag = true;
if (!currentState().isBlockTag()) {
// Opening tag still needs to be closed...
if (enforceClosingTag) {
this.writer.append(">");
}
else {
this.writer.append("/>");
renderClosingTag = false;
}
}
if (renderClosingTag) {
this.writer.append("</").append(currentState().getTagName()).append(">");
}
this.tagState.pop();
}
/**
* Adds the supplied tag name to the {@link #tagState tag state}.
*/
private void push(String tagName) {
this.tagState.push(new TagStateEntry(tagName));
}
/**
* Closes the current opening tag and marks it as a block tag.
*/
private void closeTagAndMarkAsBlock() throws JspException {
if (!currentState().isBlockTag()) {
currentState().markAsBlockTag();
this.writer.append(">");
}
}
private boolean inTag() {
return this.tagState.size() > 0;
}
private TagStateEntry currentState() {
return this.tagState.peek();
}
public void writeInnerText(String text) throws JspException{
if (inTag()) {
closeTagAndMarkAsBlock();
}
this.writer.append(text);
}
/**
* Holds state about a tag and its rendered behavior.
*/
private static class TagStateEntry {
private final String tagName;
private boolean blockTag;
public TagStateEntry(String tagName) {
this.tagName = tagName;
}
public String getTagName() {
return this.tagName;
}
public void markAsBlockTag() {
this.blockTag = true;
}
public boolean isBlockTag() {
return this.blockTag;
}
}
/**
* Simple {@link Writer} wrapper that wraps all
* {@link IOException IOExceptions} in {@link JspException JspExceptions}.
*/
private static final class SafeWriter {
private PageContext pageContext;
private Writer writer;
public SafeWriter(PageContext pageContext) {
this.pageContext = pageContext;
}
public SafeWriter(Writer writer) {
this.writer = writer;
}
public SafeWriter append(String value) throws JspException {
try {
getWriterToUse().write(String.valueOf(value));
return this;
}
catch (IOException ex) {
throw new JspException("Unable to write to JspWriter", ex);
}
}
private Writer getWriterToUse() {
return (this.pageContext != null ? this.pageContext.getOut() : this.writer);
}
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.