View Javadoc

1   /*
2    * Copyright [2007] [University Corporation for Advanced Internet Development, Inc.]
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 edu.internet2.middleware.shibboleth.common.profile.provider;
18  
19  import java.io.IOException;
20  import java.io.OutputStreamWriter;
21  
22  import org.apache.velocity.Template;
23  import org.apache.velocity.VelocityContext;
24  import org.apache.velocity.app.VelocityEngine;
25  import org.apache.velocity.runtime.resource.util.StringResourceRepository;
26  import org.opensaml.ws.transport.InTransport;
27  import org.opensaml.ws.transport.OutTransport;
28  import org.opensaml.xml.util.DatatypeHelper;
29  import org.slf4j.Logger;
30  import org.slf4j.LoggerFactory;
31  
32  import edu.internet2.middleware.shibboleth.common.profile.AbstractErrorHandler;
33  import edu.internet2.middleware.shibboleth.common.util.StringResourceLoader;
34  
35  /**
36   * An error handler that render an error page by means of evaluating a Velocity template..
37   * 
38   * The following attributes are available within the velocity context page:
39   * 
40   * <table>
41   * <th>
42   * <td>Attribute Name</td>
43   * <td>Object Type</td>
44   * <td>Value</td>
45   * </th>
46   * <tr>
47   * <td>requestError</td>
48   * <td>{@link Throwable}</td>
49   * <td>Error that was thrown that triggered the invocation of this handler. </td>
50   * </tr>
51   * </table>
52   */
53  public class VelocityErrorHandler extends AbstractErrorHandler {
54  
55      /** Class logger. */
56      private final Logger log = LoggerFactory.getLogger(VelocityErrorHandler.class);
57  
58      /** Velocity engine used to render error page. */
59      private VelocityEngine velocityEngine;
60  
61      /** Classpath location of the template to use to render the error page. */
62      private String templatePath;
63  
64      /**
65       * Constructor.
66       * 
67       * @param engine engine used to render error page
68       * @param template classpath location of template used to render error page
69       */
70      public VelocityErrorHandler(VelocityEngine engine, String template) {
71          if (engine == null) {
72              log.error("Velocity engine may not be null");
73              throw new IllegalArgumentException("Velocity engine may not be null");
74          }
75          velocityEngine = engine;
76  
77          templatePath = DatatypeHelper.safeTrimOrNullString(template);
78          if (templatePath == null) {
79              log.error("Velocity template path may not be null or empty");
80              throw new IllegalArgumentException("Velocity template path may not be null or empty");
81          }
82      }
83  
84      /**
85       * Initializes this error handler by loading the velocity template into the engine.
86       * 
87       * @throws IOException thrown if there is a problem reading the template file
88       */
89      public void initialize() throws IOException {
90          String templateString = DatatypeHelper.inputstreamToString(getClass().getResourceAsStream(templatePath), null);
91          StringResourceRepository repository = StringResourceLoader.getRepository();
92  
93          repository.putStringResource(templatePath, templateString);
94      }
95  
96      /** {@inheritDoc} */
97      public void processRequest(InTransport in, OutTransport out) {
98          VelocityContext context = new VelocityContext();
99          context.put("requestError", in.getAttribute(AbstractErrorHandler.ERROR_KEY));
100 
101         try {
102             OutputStreamWriter responseWriter = new OutputStreamWriter(out.getOutgoingStream());
103             Template template = velocityEngine.getTemplate(templatePath);
104             template.merge(context, responseWriter);
105             responseWriter.flush();
106         } catch (Throwable t) {
107             log.error("Unable to evaluate velocity error template", t);
108         }
109 
110         return;
111     }
112 }