View Javadoc

1   /*
2    * Copyright 2000-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.apache.jetspeed.portal.portlets;
18  
19  //Element Construction Set
20  import org.apache.ecs.ConcreteElement;
21  import org.apache.ecs.StringElement;
22  
23  //Jetspeed stuff
24  import org.apache.jetspeed.portal.PortletConfig;
25  import org.apache.jetspeed.portal.PortletException;
26  import org.apache.jetspeed.util.JetspeedClearElement;
27  import org.apache.jetspeed.util.MimeType;
28  import org.apache.jetspeed.cache.disk.JetspeedDiskCache;
29  import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
30  import org.apache.jetspeed.services.logging.JetspeedLogger;
31  
32  //turbine
33  import org.apache.turbine.util.RunData;
34  
35  //standard java stuff
36  import java.io.ByteArrayOutputStream;
37  import java.io.IOException;
38  import java.io.PrintWriter;
39  import java.io.UnsupportedEncodingException;
40  
41  
42  import org.xml.sax.AttributeList;
43  import org.xml.sax.HandlerBase;
44  import org.xml.sax.Parser;
45  import org.xml.sax.SAXParseException;
46  import org.xml.sax.SAXException;
47  import org.xml.sax.helpers.ParserFactory;
48  
49  /***
50   * This portlet serves well-formed WML file content and strips
51   * them of superfluous tags liks <wml>
52   *
53   * <strong>The strip capability has been temporarily disabled due to
54   * class conflicts in Tomcat 3.2, so this portlet can only currently
55   * serve fragments of WML documents, without the <wml> tag</strong>
56   *
57   * @author <a href="mailto:raphael@apache.org">Raphaël Luta</a>
58   * @version $Id: WMLFilePortlet.java,v 1.11 2004/02/23 04:03:33 jford Exp $ 
59   */
60  public class WMLFilePortlet extends FileWatchPortlet 
61  {
62      /***
63       * Static initialization of the logger for this class
64       */    
65      private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(WMLFilePortlet.class.getName());
66      
67      private ConcreteElement content = new StringElement("Not available");
68      
69      /***
70        * @see Portlet#supportsType
71        */
72      public boolean supportsType( MimeType type ) {
73          return type.equals(MimeType.WML);
74      }
75   
76      /*** Initialize the content of the portlet
77      */
78      public void init() throws PortletException {
79  
80          PortletConfig config = this.getPortletConfig();
81          ByteArrayOutputStream bos = new ByteArrayOutputStream();
82   
83          try {
84              // RL: disable the SAX filter due to a class path problem
85              // with Tomcat 3.2
86              /*
87              String url = JetspeedDiskCache.getInstance().getEntry( config.getURL() ).getURL();
88  
89              WMLFilter myFilter = new WMLFilter(new PrintWriter(bos));
90              myFilter.filter(url);
91              content = new JetspeedClearElement( bos.toString() );
92              */
93              content = new JetspeedClearElement(
94                  JetspeedDiskCache.getInstance().getEntry( config.getURL() ).getData() );
95          } catch (Exception e) {
96              throw new PortletException( e.getMessage() );
97          } finally {
98              try {
99                  bos.close();
100             } catch (IOException e) {}
101         }
102     }
103 
104     public ConcreteElement getContent( RunData data ) {
105         return content;
106     }
107     
108     class WMLFilter extends HandlerBase {
109     
110         private static final String DEFAULT_PARSER_NAME = "javax.xml.parsers.SAXParser";
111 
112         protected PrintWriter out=new PrintWriter(System.out);
113 
114         public WMLFilter(PrintWriter outPW) throws UnsupportedEncodingException {
115             this.out=outPW;
116         }
117 
118         public void filter(String uri) {
119 
120             try {
121                 HandlerBase handler = this;
122     
123                 Parser parser = ParserFactory.makeParser(DEFAULT_PARSER_NAME);
124                 parser.setDocumentHandler(handler);
125                 parser.setErrorHandler(handler);
126                 parser.parse(uri);
127             }
128             catch (Exception e) {
129                 logger.error("Exception",  e);
130             }
131         }
132 
133         public void processingInstruction(String target, String data) {        
134             //filter all PIs
135         }
136 
137         public void startElement(String name, AttributeList attrs) {
138 
139             // strip <wml>
140             if (name.equals("wml")) return;
141 
142             // else output the element        
143             out.print('<');
144             out.print(name);
145             if (attrs != null) {
146                 int len = attrs.getLength();
147                 for (int i = 0; i < len; i++) {
148                     out.print(' ');
149                     out.print(attrs.getName(i));
150                     out.print("=\"");
151                     out.print(normalize(attrs.getValue(i)));
152                     out.print('"');
153                 }
154             }
155             out.print('>');    
156         }
157 
158         public void characters(char ch[], int start, int length) {
159             out.print(normalize(new String(ch, start, length)));
160         }
161 
162         public void ignorableWhitespace(char ch[], int start, int length) {
163             characters(ch, start, length);
164         }
165 
166         public void endElement(String name) {
167             //filter <wml>
168             if (name.equals("wml")) return;
169             
170             // outpu anything else
171             out.print("</");
172             out.print(name);
173             out.print('>');
174         }
175 
176         public void endDocument() {
177             out.flush();
178         }
179 
180         public void warning(SAXParseException ex) {
181             logger.info(getLocationString(ex)+": "+ex.getMessage());
182         }
183 
184         public void error(SAXParseException ex) {
185             logger.error(getLocationString(ex)+": "+ex, ex);
186         }
187 
188         public void fatalError(SAXParseException ex) throws SAXException {
189             logger.error(getLocationString(ex)+": "+ex, ex);
190             throw ex;
191         }
192 
193         /***
194         Retrieves the error location in the input stream
195         */
196         private String getLocationString(SAXParseException ex) {
197             StringBuffer str = new StringBuffer();
198     
199             String systemId = ex.getSystemId();
200             if (systemId != null) {
201                 int index = systemId.lastIndexOf('/');
202                 if (index != -1)
203                     systemId = systemId.substring(index + 1);
204                 str.append(systemId);
205             }
206             str.append(':');
207             str.append(ex.getLineNumber());
208             str.append(':');
209             str.append(ex.getColumnNumber());
210     
211             return str.toString();
212     
213         }
214 
215         /***
216         Escapes characters data
217         */
218         protected String normalize(String s) {
219             StringBuffer str = new StringBuffer();
220     
221             int len = (s != null) ? s.length() : 0;
222             for (int i = 0; i < len; i++) {
223                 char ch = s.charAt(i);
224                 switch (ch) {
225                     case '<': {
226                         str.append("&lt;");
227                         break;
228                     }
229                     case '>': {
230                         str.append("&gt;");
231                         break;
232                     }
233                     case '&': {
234                         str.append("&amp;");
235                         break;
236                     }
237                     case '"': {
238                         str.append("&quot;");
239                         break;
240                     }
241                     default: {
242                         str.append(ch);
243                     }
244                 }
245             }
246 
247             return str.toString();
248 
249         }
250     }
251 }