2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6
* The contents of this file are subject to the terms of either the GNU
7
* General Public License Version 2 only ("GPL") or the Common
8
* Development and Distribution License("CDDL") (collectively, the
9
* "License"). You may not use this file except in compliance with the
10
* License. You can obtain a copy of the License at
11
* http://www.netbeans.org/cddl-gplv2.html
12
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
* specific language governing permissions and limitations under the
14
* License. When distributing the software, include this License Header
15
* Notice in each file and include the License file at
16
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17
* particular file as subject to the "Classpath" exception as provided
18
* by Sun in the GPL Version 2 section of the License file that
19
* accompanied this code. If applicable, add the following below the
20
* License Header, with the fields enclosed by brackets [] replaced by
21
* your own identifying information:
22
* "Portions Copyrighted [year] [name of copyright owner]"
26
* The Original Software is NetBeans. The Initial Developer of the Original
27
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
* Microsystems, Inc. All Rights Reserved.
30
* If you wish your version of this file to be governed by only the CDDL
31
* or only the GPL Version 2, indicate your decision by adding
32
* "[Contributor] elects to include this software in this distribution
33
* under the [CDDL or GPL Version 2] license." If you do not indicate a
34
* single choice of license, a recipient has the option to distribute
35
* your version of this file under either the CDDL, the GPL Version 2 or
36
* to extend the choice of license to its licensees as provided above.
37
* However, if you add GPL Version 2 code and therefore, elected the GPL
38
* Version 2 license, then the option applies only if the new code is
39
* made subject to such option by the copyright holder.
42
package org.netbeans.modules.xsl.transform;
44
import java.io.IOException;
45
import java.io.PrintWriter;
46
import java.net.MalformedURLException;
48
import java.net.UnknownHostException;
49
import java.util.Iterator;
50
import java.util.List;
51
import java.util.Vector;
52
import javax.servlet.ServletConfig;
53
import javax.servlet.ServletException;
54
import javax.servlet.http.HttpServlet;
55
import javax.servlet.http.HttpServletRequest;
56
import javax.servlet.http.HttpServletResponse;
57
import javax.xml.transform.Result;
58
import javax.xml.transform.Source;
59
import javax.xml.transform.TransformerException;
60
import javax.xml.transform.stream.StreamResult;
61
import org.netbeans.api.xml.cookies.CookieMessage;
62
import org.netbeans.api.xml.cookies.CookieObserver;
63
import org.netbeans.api.xml.cookies.TransformableCookie;
64
import org.netbeans.api.xml.cookies.XMLProcessorDetail;
65
import org.netbeans.modules.xsl.utils.TransformUtil;
66
import org.netbeans.spi.xml.cookies.DefaultXMLProcessorDetail;
67
import org.openide.filesystems.FileObject;
68
import org.openide.filesystems.FileSystem;
69
import org.openide.filesystems.Repository;
70
import org.openide.filesystems.URLMapper;
71
import org.xml.sax.SAXParseException;
75
* @author Libor Kramolis
77
public class TransformServlet extends HttpServlet {
78
private static final long serialVersionUID = 1632869007241230624L;
80
private static TransformableCookie transformable;
81
/** Last cached XML Source. */
82
private static Source xmlSource;
83
/** Last cached XSL Script. */
84
private static Source xslSource;
87
public static void prepare (TransformableCookie trans, Source xml, Source xsl) {
88
transformable = trans;
93
/** Initializes the servlet.
95
public void init (ServletConfig config) throws ServletException {
99
/** Destroys the servlet.
101
public void destroy () {
106
/** Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
107
* @param request servlet request
108
* @param response servlet response
110
protected void processRequest (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
111
PrintWriter out = response.getWriter();
112
Result outputResult = new StreamResult (out);
114
Observer notifier = new Observer();
116
String guessOutputExt = TransformUtil.guessOutputExt (xslSource);
118
if (guessOutputExt.equals("txt")) { // NOI18N
119
mimeType = "text/plain"; // NOI18N
120
} else if (guessOutputExt.equals("xml")) { // NOI18N
121
mimeType = "text/xml"; // NOI18N
122
} else if (guessOutputExt.equals("html")) { // NOI18N
123
mimeType = "text/html"; // NOI18N
128
if ( mimeType != null ) {
129
response.setContentType (mimeType);
132
if ( Util.THIS.isLoggable() ) /* then */ {
133
Util.THIS.debug ("[TransformServlet] Response MIME Type: '" + mimeType + "'");
134
Util.THIS.debug (" xmlSource.getSystemId() = " + xmlSource.getSystemId());
135
Util.THIS.debug (" transformable = " + transformable);
136
Util.THIS.debug (" xslSource.getSystemId() = " + xslSource.getSystemId());
139
TransformUtil.transform (xmlSource, transformable, xslSource, outputResult, notifier);
140
} catch (Exception exc) {
141
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug (" EXCEPTION!!!: " + exc.getClass().getName(), exc);
143
// thrown if error in style sheet
144
CookieMessage message = null;
146
if ( exc instanceof TransformerException ) {
147
// do not log again TransformerException, it is already done by ErrorListener
148
} else if ( exc instanceof SAXParseException ) {
149
message = new CookieMessage
150
(TransformUtil.unwrapException (exc).getLocalizedMessage(),
151
CookieMessage.FATAL_ERROR_LEVEL,
152
new DefaultXMLProcessorDetail ((SAXParseException) exc)
155
message = new CookieMessage
156
(exc.getLocalizedMessage(),
157
CookieMessage.FATAL_ERROR_LEVEL
161
if ( Util.THIS.isLoggable() ) /* then */ {
162
Util.THIS.debug (" message = " + message);
163
Util.THIS.debug (" notifier = " + notifier);
166
if ( message != null ) {
167
notifier.receive (message);
170
// create warning page
171
response.setContentType ("text/html");
173
out.println ("<html><head>");
174
out.println (" <title>" + Util.THIS.getString ("MSG_error_html_title") + "</title>");
175
out.println (" <style>" + Util.THIS.getString ("MSG_error_html_style") + "</style>");
176
out.println ("</head><body>");
177
out.println (" <h2>" + Util.THIS.getString ("MSG_error_page_title") + "</h2>");
178
out.println (" <p>" + Util.THIS.getString ("MSG_error_page_message") + "</p>");
179
out.println (" <hr size=\"1\" noshade=\"\" />\n" + generateReport (notifier.getList()) + "<hr size=\"1\" noshade=\"\" />");
180
out.println (" <p>" + Util.THIS.getString ("MSG_error_bottom_message") + "</p>");
181
out.println ("</body></html>");
187
/** Handles the HTTP <code>GET</code> method.
188
* @param request servlet request
189
* @param response servlet response
191
protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
192
processRequest (request, response);
195
/** Handles the HTTP <code>POST</code> method.
196
* @param request servlet request
197
* @param response servlet response
199
protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
200
processRequest (request, response);
203
/** Returns a short description of the servlet.
205
public String getServletInfo () {
206
return "XSL Transformation Preview Servlet";
209
public static URL getServletURL () throws MalformedURLException, UnknownHostException {
211
URL base = getSampleHTTPServerURL();
212
// XXX hack: assume that the path /servlet/CLASSNAME works on this server.
213
URL root = new URL (base.getProtocol(), base.getHost(), base.getPort(), "/servlet/" + TransformServlet.class.getName() + "/");
218
private static URL getSampleHTTPServerURL() {
219
FileSystem fs = Repository.getDefault().getDefaultFileSystem();
220
FileObject fo = fs.findResource("HTTPServer_DUMMY");
224
URL u = URLMapper.findURL(fo, URLMapper.NETWORK);
228
private String generateReport (List msgList) {
229
StringBuffer sb = new StringBuffer();
233
Iterator it = msgList.iterator();
234
while ( it.hasNext() ) {
235
CookieMessage msg = (CookieMessage) it.next();
236
XMLProcessorDetail detail = (XMLProcessorDetail) msg.getDetail (XMLProcessorDetail.class);
239
sb.append (" <font class=\"").append (levelName (msg.getLevel())).append ("\">").append (msg.getMessage()).append ("</font>"); // NOI18N
241
if ( detail != null ) {
243
String systemId = preferFileName (detail.getSystemId());
244
if ( systemId != null ) {
245
sb.append (" (<font class=\"system-id\">");
246
boolean isFile = systemId.startsWith ("file:");
248
sb.append ("<a href=\"").append (systemId).append ("\">");
250
sb.append (systemId);
254
sb.append ("</font>\n"); // NOI18N
256
sb.append (" [<font class=\"line-number\">").append (detail.getLineNumber()).append ("</font>])<br>"); // NOI18N
261
} catch (Exception exc) {
262
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug (exc);
265
return sb.toString();
269
private String preferFileName (String systemId) {
270
String name = systemId;
273
URL url = new URL (systemId);
274
FileObject fo = URLMapper.findFileObject(url);
276
name = TransformUtil.getURLName (fo);
278
} catch (Exception exc) {
279
// ignore it -> use systemId
281
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug (exc);
287
private String levelName (int level) {
288
if ( level == CookieMessage.FATAL_ERROR_LEVEL ) {
289
return "fatal-error"; // NOI18N
290
} else if ( level == CookieMessage.ERROR_LEVEL ) {
291
return "error"; // NOI18N
292
} else if ( level == CookieMessage.WARNING_LEVEL ) {
293
return "warning"; // NOI18N
294
} else { // CookieMessage.INFORMATIONAL_LEVEL
295
return "informational"; // NOI18N
304
private static class Observer implements CookieObserver {
306
private final List msgList;
309
msgList = new Vector();
312
public void receive (CookieMessage msg) {
316
public List getList () {