001: package com.icesoft.faces.context;
002:
003: import com.icesoft.faces.application.StartupTime;
004: import com.icesoft.faces.util.DOMUtils;
005: import com.icesoft.faces.util.CoreUtils;
006: import com.icesoft.faces.context.effects.JavascriptContext;
007: import com.icesoft.jasper.Constants;
008: import org.w3c.dom.Document;
009: import org.w3c.dom.Node;
010: import org.apache.commons.logging.Log;
011: import org.apache.commons.logging.LogFactory;
012:
013: import javax.faces.context.ExternalContext;
014: import java.io.IOException;
015: import java.io.Writer;
016: import java.util.Map;
017:
018: public class NormalModeSerializer implements DOMSerializer {
019:
020: private static Log log = LogFactory
021: .getLog(NormalModeSerializer.class);
022:
023: private BridgeFacesContext context;
024: private Writer writer;
025:
026: public NormalModeSerializer(BridgeFacesContext context,
027: Writer writer) {
028: this .context = context;
029: this .writer = writer;
030: }
031:
032: public void serialize(Document document) throws IOException {
033: Map requestMap = context.getExternalContext().getRequestMap();
034:
035: if (isFragment(requestMap)) {
036: if (log.isDebugEnabled()) {
037: log.debug("treating request as a fragment");
038: }
039:
040: Node body = DOMUtils.getChildByNodeName(document
041: .getDocumentElement(), "body");
042: if (null != body) {
043:
044: //We need to include, for now, ICE_EXTRAS all the time to
045: //ensure that it is available.
046: writer
047: .write(makeScriptEntry(JavascriptContext.ICE_BRIDGE));
048: writer
049: .write(makeScriptEntry(JavascriptContext.ICE_EXTRAS));
050:
051: writer.write(DOMUtils.childrenToString(body));
052: }
053: } else {
054: if (log.isDebugEnabled()) {
055: log
056: .debug("treating request as a whole page (not a fragment)");
057: }
058:
059: String publicID = (String) requestMap
060: .get(DOMResponseWriter.DOCTYPE_PUBLIC);
061: String systemID = (String) requestMap
062: .get(DOMResponseWriter.DOCTYPE_SYSTEM);
063: String root = (String) requestMap
064: .get(DOMResponseWriter.DOCTYPE_ROOT);
065: String output = (String) requestMap
066: .get(DOMResponseWriter.DOCTYPE_OUTPUT);
067: boolean prettyPrinting = Boolean
068: .valueOf(
069: (String) requestMap
070: .get(DOMResponseWriter.DOCTYPE_PRETTY_PRINTING))
071: .booleanValue();
072:
073: //todo: replace this with a complete new implementation that doesn't rely on xslt but can serialize xml, xhtml, and html.
074: if (output == null
075: || ("html".equals(output) && !prettyPrinting)) {
076: if (publicID != null && systemID != null
077: && root != null) {
078: writer.write(DOMUtils.DocumentTypetoString(
079: publicID, systemID, root));
080: }
081: writer.write(DOMUtils.DOMtoString(document));
082: } else {
083: //use a serializer. not as performant.
084: JAXPSerializer serializer = new JAXPSerializer(writer,
085: publicID, systemID);
086: if ("xml".equals(output)) {
087: serializer.outputAsXML();
088: } else {
089: serializer.outputAsHTML();
090: }
091: if (prettyPrinting) {
092: serializer.printPretty();
093: }
094: serializer.serialize(document);
095: }
096: }
097:
098: writer.flush();
099: }
100:
101: private String makeScriptEntry(String src) {
102: return "<script language='javascript' src='"
103: + CoreUtils.resolveResourceURL(context, src)
104: + "'></script>";
105: }
106:
107: private boolean isFragment(Map requestMap) {
108: //TODO - assuming we can handle portlets just like includes, then
109: //we can probably reduce the attributes that we check for. We need
110: //to be specific about when to use request URI and when to use servlet
111: //path.
112:
113: String frag = (String) requestMap
114: .get(Constants.INC_REQUEST_URI);
115: if (log.isDebugEnabled()) {
116: log.debug(Constants.INC_REQUEST_URI + " = " + frag);
117: }
118: if (frag != null) {
119: return true;
120: }
121:
122: frag = (String) requestMap.get(Constants.INC_SERVLET_PATH);
123: if (log.isDebugEnabled()) {
124: log.debug(Constants.INC_SERVLET_PATH + " = " + frag);
125: }
126: if (frag != null) {
127: return true;
128: }
129:
130: //This type of check should no longer be required. If we need
131: //to put a portlet specific attribute back in, then we should
132: //define our own.
133: frag = (String) requestMap.get("com.sun.faces.portlet.INIT");
134: if (frag != null) {
135: return true;
136: }
137:
138: return false;
139: }
140: }
|