001    package org.apache.turbine.modules.screens;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *   http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import org.apache.commons.lang.StringUtils;
023    import org.apache.commons.lang.exception.ExceptionUtils;
024    import org.apache.ecs.ConcreteElement;
025    import org.apache.ecs.StringElement;
026    import org.apache.turbine.Turbine;
027    import org.apache.turbine.TurbineConstants;
028    import org.apache.turbine.pipeline.PipelineData;
029    import org.apache.turbine.services.template.TurbineTemplate;
030    import org.apache.turbine.services.velocity.TurbineVelocity;
031    import org.apache.turbine.util.RunData;
032    import org.apache.velocity.context.Context;
033    
034    /**
035     * Base Velocity Screen.  The buildTemplate() assumes the template
036     * parameter has been set in the RunData object.  This provides the
037     * ability to execute several templates from one Screen.
038     *
039     * <p>
040     *
041     * If you need more specific behavior in your application, extend this
042     * class and override the doBuildTemplate() method.
043     *
044     * @author <a href="mailto:mbryson@mont.mindspring.com">Dave Bryson</a>
045     * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
046     * @author <a href="mailto:peter@courcoux.biz">Peter Courcoux</a>
047     * @version $Id: VelocityScreen.java 1078552 2011-03-06 19:58:46Z tv $
048     */
049    public class VelocityScreen
050        extends TemplateScreen
051    {
052        /** The prefix for lookup up screen pages */
053        private final String prefix = getPrefix() + "/";
054    
055        /**
056         * Velocity Screens extending this class should overide this
057         * method to perform any particular business logic and add
058         * information to the context.
059         *
060         * @deprecated Use PipelineData version instead.
061         * @param data Turbine information.
062         * @param context Context for web pages.
063         * @exception Exception, a generic exception.
064         */
065        @Deprecated
066        protected void doBuildTemplate(RunData data,
067                                       Context context)
068                throws Exception
069        {
070            // empty
071        }
072    
073        /**
074         * Velocity Screens extending this class should overide this
075         * method to perform any particular business logic and add
076         * information to the context.
077         *
078         * @param pipelineData Turbine information.
079         * @param context Context for web pages.
080         * @exception Exception, a generic exception.
081         */
082        protected void doBuildTemplate(PipelineData pipelineData,
083                                       Context context)
084                throws Exception
085        {
086            // empty
087        }
088    
089    
090        /**
091         * Needs to be implemented to make TemplateScreen like us.  The
092         * actual method that you should override is the one with the
093         * context in the parameter list.
094         *
095         * @deprecated Use PipelineData version instead.
096         * @param data Turbine information.
097         * @exception Exception, a generic exception.
098         */
099        @Deprecated
100        @Override
101        protected void doBuildTemplate(RunData data)
102                throws Exception
103        {
104            doBuildTemplate(data, TurbineVelocity.getContext(data));
105        }
106    
107        /**
108         * Needs to be implemented to make TemplateScreen like us.  The
109         * actual method that you should override is the one with the
110         * context in the parameter list.
111         *
112         * @param data Turbine information.
113         * @exception Exception, a generic exception.
114         */
115        @Override
116        protected void doBuildTemplate(PipelineData pipelineData)
117                throws Exception
118        {
119            doBuildTemplate(pipelineData, TurbineVelocity.getContext(pipelineData));
120        }
121    
122    
123    
124        /**
125         * This builds the Velocity template.
126         *
127         * @deprecated Use PipelineData version instead.
128         * @param data Turbine information.
129         * @return A ConcreteElement.
130         * @exception Exception, a generic exception.
131         */
132        @Deprecated
133        @Override
134        public ConcreteElement buildTemplate(RunData data)
135            throws Exception
136        {
137            String screenData = null;
138    
139            Context context = TurbineVelocity.getContext(data);
140    
141            String screenTemplate = data.getTemplateInfo().getScreenTemplate();
142            String templateName
143                = TurbineTemplate.getScreenTemplateName(screenTemplate);
144    
145            // The Template Service could not find the Screen
146            if (StringUtils.isEmpty(templateName))
147            {
148                log.error("Screen " + screenTemplate + " not found!");
149                throw new Exception("Could not find screen for " + screenTemplate);
150            }
151    
152            try
153            {
154                // if a layout has been defined return the results, otherwise
155                // send the results directly to the output stream.
156                if (getLayout(data) == null)
157                {
158                    TurbineVelocity.handleRequest(context,
159                            prefix + templateName,
160                            data.getResponse().getOutputStream());
161                }
162                else
163                {
164                    screenData = TurbineVelocity
165                            .handleRequest(context, prefix + templateName);
166                }
167            }
168            catch (Exception e)
169            {
170                // If there is an error, build a $processingException and
171                // attempt to call the error.vm template in the screens
172                // directory.
173                context.put (TurbineConstants.PROCESSING_EXCEPTION_PLACEHOLDER, e.toString());
174                context.put (TurbineConstants.STACK_TRACE_PLACEHOLDER, ExceptionUtils.getStackTrace(e));
175    
176                templateName = Turbine.getConfiguration()
177                    .getString(TurbineConstants.TEMPLATE_ERROR_KEY,
178                               TurbineConstants.TEMPLATE_ERROR_VM);
179    
180                screenData = TurbineVelocity.handleRequest(
181                    context, prefix + templateName);
182            }
183    
184            // package the response in an ECS element
185            StringElement output = new StringElement();
186            output.setFilterState(false);
187    
188            if (screenData != null)
189            {
190                output.addElement(screenData);
191            }
192            return output;
193        }
194    
195        /**
196         * This builds the Velocity template.
197         *
198         * @param data Turbine information.
199         * @return A ConcreteElement.
200         * @exception Exception, a generic exception.
201         */
202        @Override
203        public ConcreteElement buildTemplate(PipelineData pipelineData)
204            throws Exception
205        {
206            RunData data = getRunData(pipelineData);
207            String screenData = null;
208    
209            Context context = TurbineVelocity.getContext(pipelineData);
210    
211            String screenTemplate = data.getTemplateInfo().getScreenTemplate();
212            String templateName
213                = TurbineTemplate.getScreenTemplateName(screenTemplate);
214    
215            // The Template Service could not find the Screen
216            if (StringUtils.isEmpty(templateName))
217            {
218                log.error("Screen " + screenTemplate + " not found!");
219                throw new Exception("Could not find screen for " + screenTemplate);
220            }
221    
222            try
223            {
224                // if a layout has been defined return the results, otherwise
225                // send the results directly to the output stream.
226                if (getLayout(pipelineData) == null)
227                {
228                    TurbineVelocity.handleRequest(context,
229                            prefix + templateName,
230                            data.getResponse().getOutputStream());
231                }
232                else
233                {
234                    screenData = TurbineVelocity
235                            .handleRequest(context, prefix + templateName);
236                }
237            }
238            catch (Exception e)
239            {
240                // If there is an error, build a $processingException and
241                // attempt to call the error.vm template in the screens
242                // directory.
243                context.put (TurbineConstants.PROCESSING_EXCEPTION_PLACEHOLDER, e.toString());
244                context.put (TurbineConstants.STACK_TRACE_PLACEHOLDER, ExceptionUtils.getStackTrace(e));
245    
246                templateName = Turbine.getConfiguration()
247                    .getString(TurbineConstants.TEMPLATE_ERROR_KEY,
248                               TurbineConstants.TEMPLATE_ERROR_VM);
249    
250                screenData = TurbineVelocity.handleRequest(
251                    context, prefix + templateName);
252            }
253    
254            // package the response in an ECS element
255            StringElement output = new StringElement();
256            output.setFilterState(false);
257    
258            if (screenData != null)
259            {
260                output.addElement(screenData);
261            }
262            return output;
263        }
264    
265    
266        /**
267         * Return the Context needed by Velocity.
268         *
269         * @param data Turbine information.
270         * @return A Context.
271         *
272         * @deprecated Use TurbineVelocity.getContext(data)
273         */
274        @Deprecated
275        public static Context getContext(RunData data)
276        {
277            return TurbineVelocity.getContext(data);
278        }
279    
280        /**
281         * Return the Context needed by Velocity.
282         *
283         * @param data Turbine information.
284         * @return A Context.
285         *
286         * @deprecated Use TurbineVelocity.getContext(pipelineData)
287         */
288        @Deprecated
289        public static Context getContext(PipelineData pipelineData)
290        {
291            return TurbineVelocity.getContext(pipelineData);
292        }
293    
294    }