001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.components.notification;
018:
019: import org.apache.cocoon.Constants;
020: import org.apache.cocoon.xml.XMLUtils;
021:
022: import org.apache.commons.lang.StringEscapeUtils;
023: import org.xml.sax.ContentHandler;
024: import org.xml.sax.SAXException;
025: import org.xml.sax.helpers.AttributesImpl;
026:
027: import java.io.IOException;
028: import java.io.OutputStream;
029: import java.util.Iterator;
030: import java.util.Map;
031:
032: /**
033: * Generates a representations of the specified Notifying Object.
034: *
035: * @author <a href="mailto:nicolaken@supereva.it">Nicola Ken Barozzi</a>
036: * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
037: * @version $Id: Notifier.java 433543 2006-08-22 06:22:54Z crossley $
038: */
039: public class Notifier {
040:
041: /**
042: * Generate notification information as a response.
043: * The notification is directly written to the OutputStream.
044: * @param n The <code>Notifying</code> object
045: * @param outputStream The output stream the notification is written to
046: * This could be <code>null</code>.
047: */
048: public static void notify(Notifying n, OutputStream outputStream,
049: String mimetype) throws IOException {
050: //(NKB) FIXME should use error page templates, one per mime-type
051: // currently uses hardcoded html, should be used only as last resort.
052: notifyHTML(n, outputStream);
053: }
054:
055: /**
056: * Generate notification information as html.
057: * The notification is directly written to the OutputStream.
058: * @param n The <code>Notifying</code> object
059: * @param outputStream The output stream the notification is written to
060: * This could be <code>null</code>.
061: */
062: private static void notifyHTML(Notifying n,
063: OutputStream outputStream) throws IOException {
064: if (outputStream == null) {
065: return;
066: }
067:
068: StringBuffer sb = new StringBuffer();
069:
070: sb.append("<html><head><title>").append(n.getTitle()).append(
071: "</title>");
072: sb.append("<style><!--");
073: sb
074: .append("body { background-color: white; color: black; font-family: verdana, helvetica, sanf serif;}");
075: sb
076: .append("h1 {color: #336699; margin: 0px 0px 20px 0px; border-width: 0px 0px 1px 0px; border-style: solid; border-color: #336699;}");
077: sb
078: .append("p.footer { color: #336699; border-width: 1px 0px 0px 0px; border-style: solid; border-color: #336699; }");
079: sb.append("span {color: #336699;}");
080: sb.append("pre {padding-left: 20px;}");
081: sb.append("a:link {font-weight: bold; color: #336699;}");
082: sb.append("a:visited {color: #336699; }");
083: sb
084: .append("a:hover {color: #800000; background-color: #ffff80;}");
085: sb.append("a:active {color: #006666;}");
086: sb.append("--></style>");
087: sb.append("</head><body>");
088: sb.append("<h1>").append(
089: StringEscapeUtils.escapeXml(n.getTitle())).append(
090: "</h1>");
091: sb.append("<p><span>Message:</span> ").append(
092: StringEscapeUtils.escapeXml(n.getMessage())).append(
093: "</p>");
094: sb.append("<p><span>Description:</span> ").append(
095: StringEscapeUtils.escapeXml(n.getDescription()))
096: .append("</p>");
097: sb.append("<p><span>Sender:</span> ").append(
098: StringEscapeUtils.escapeXml(n.getSender())).append(
099: "</p>");
100: sb.append("<p><span>Source:</span> ").append(
101: StringEscapeUtils.escapeXml(n.getSource())).append(
102: "</p>");
103:
104: Map extras = n.getExtraDescriptions();
105: for (Iterator i = extras.entrySet().iterator(); i.hasNext();) {
106: Map.Entry me = (Map.Entry) i.next();
107: final String key = (String) me.getKey();
108: sb.append("<p><span>").append(key).append("</span><pre>")
109: .append(
110: StringEscapeUtils.escapeXml(String
111: .valueOf(me.getValue()))).append(
112: "</pre></p>");
113: }
114: sb
115: .append(
116: "<p class='footer'><a href='http://cocoon.apache.org/'>")
117: .append(Constants.COMPLETE_NAME).append("</p>");
118: sb.append("</body></html>");
119:
120: outputStream.write(sb.toString().getBytes());
121: }
122:
123: /**
124: * Generate notification information in XML format.
125: */
126: public static void notify(Notifying n, ContentHandler ch,
127: String mimetype) throws SAXException {
128: final String PREFIX = Constants.ERROR_NAMESPACE_PREFIX;
129: final String URI = Constants.ERROR_NAMESPACE_URI;
130:
131: // Start the document
132: ch.startDocument();
133: ch.startPrefixMapping(PREFIX, URI);
134:
135: // Root element.
136: AttributesImpl atts = new AttributesImpl();
137:
138: atts.addAttribute(URI, "type", PREFIX + ":type", "CDATA", n
139: .getType());
140: atts.addAttribute(URI, "sender", PREFIX + ":sender", "CDATA", n
141: .getSender());
142: ch.startElement(URI, "notify", PREFIX + ":notify", atts);
143: ch.startElement(URI, "title", PREFIX + ":title",
144: new AttributesImpl());
145: ch.characters(n.getTitle().toCharArray(), 0, n.getTitle()
146: .length());
147: ch.endElement(URI, "title", PREFIX + ":title");
148: ch.startElement(URI, "source", PREFIX + ":source",
149: new AttributesImpl());
150: ch.characters(n.getSource().toCharArray(), 0, n.getSource()
151: .length());
152: ch.endElement(URI, "source", PREFIX + ":source");
153: ch.startElement(URI, "message", PREFIX + ":message",
154: new AttributesImpl());
155:
156: if (n.getMessage() != null) {
157: ch.characters(n.getMessage().toCharArray(), 0, n
158: .getMessage().length());
159: }
160:
161: ch.endElement(URI, "message", PREFIX + ":message");
162: ch.startElement(URI, "description", PREFIX + ":description",
163: XMLUtils.EMPTY_ATTRIBUTES);
164: ch.characters(n.getDescription().toCharArray(), 0, n
165: .getDescription().length());
166: ch.endElement(URI, "description", PREFIX + ":description");
167:
168: Map extraDescriptions = n.getExtraDescriptions();
169: for (Iterator i = extraDescriptions.entrySet().iterator(); i
170: .hasNext();) {
171: final Map.Entry me = (Map.Entry) i.next();
172: String key = (String) me.getKey();
173: String value = String.valueOf(me.getValue());
174: atts = new AttributesImpl();
175: atts.addAttribute(URI, "description", PREFIX
176: + ":description", "CDATA", key);
177: ch.startElement(URI, "extra", PREFIX + ":extra", atts);
178: ch.characters(value.toCharArray(), 0, value.length());
179: ch.endElement(URI, "extra", PREFIX + ":extra");
180: }
181:
182: // End root element.
183: ch.endElement(URI, "notify", PREFIX + ":notify");
184:
185: // End the document.
186: ch.endPrefixMapping(PREFIX);
187: ch.endDocument();
188: }
189: }
|