001 // Copyright 2004, 2005 The Apache Software Foundation 002 // 003 // Licensed under the Apache License, Version 2.0 (the "License"); 004 // you may not use this file except in compliance with the License. 005 // You may obtain a copy of the License at 006 // 007 // http://www.apache.org/licenses/LICENSE-2.0 008 // 009 // Unless required by applicable law or agreed to in writing, software 010 // distributed under the License is distributed on an "AS IS" BASIS, 011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012 // See the License for the specific language governing permissions and 013 // limitations under the License. 014 015 package org.apache.tapestry.binding; 016 017 import org.apache.bsf.BSFException; 018 import org.apache.bsf.BSFManager; 019 import org.apache.hivemind.ApplicationRuntimeException; 020 import org.apache.hivemind.Location; 021 import org.apache.hivemind.util.Defense; 022 import org.apache.tapestry.IActionListener; 023 import org.apache.tapestry.IComponent; 024 import org.apache.tapestry.IPage; 025 import org.apache.tapestry.IRequestCycle; 026 import org.apache.tapestry.Tapestry; 027 import org.apache.tapestry.coerce.ValueConverter; 028 import org.apache.tapestry.services.BSFManagerFactory; 029 030 /** 031 * A very specialized binding that can be used as an {@link org.apache.tapestry.IActionListener}, 032 * executing a script in a scripting language, via <a href="http://jakarta.apache.org/bsf">Bean 033 * Scripting Framework </a>. 034 * 035 * @author Howard Lewis Ship 036 * @since 3.0 037 */ 038 039 public class ListenerBinding extends AbstractBinding implements IActionListener 040 { 041 private final String _language; 042 043 private final String _script; 044 045 private final IComponent _component; 046 047 /** @since 4.0 */ 048 049 private BSFManagerFactory _managerFactory; 050 051 public ListenerBinding(String description, ValueConverter valueConverter, Location location, 052 IComponent component, String language, String script, 053 BSFManagerFactory managerFactory) 054 { 055 super(description, valueConverter, location); 056 057 Defense.notNull(component, "component"); 058 Defense.notNull(language, "language"); 059 Defense.notNull(script, "script"); 060 061 _component = component; 062 _language = language; 063 _script = script; 064 _managerFactory = managerFactory; 065 } 066 067 /** 068 * Returns this. 069 */ 070 071 public Object getObject() 072 { 073 return this; 074 } 075 076 /** 077 * A ListenerBinding is also a {@link org.apache.tapestry.IActionListener}. It registers a 078 * number of beans with the BSF manager and invokes the script. 079 * <p> 080 * Registers the following bean: 081 * <ul> 082 * <li>component - the relevant {@link IComponent}, typically the same as the page 083 * <li>page - the {@link IPage}trigged by the request (obtained by 084 * {@link IRequestCycle#getPage()} 085 * <li>cycle - the {@link IRequestCycle}, from which can be found the {@link IEngine}, etc. 086 * </ul> 087 */ 088 089 public void actionTriggered(IComponent component, IRequestCycle cycle) 090 { 091 BSFManager bsf = _managerFactory.createBSFManager(); 092 093 Location location = getLocation(); 094 095 try 096 { 097 IPage page = cycle.getPage(); 098 099 bsf.declareBean("component", _component, _component.getClass()); 100 bsf.declareBean("page", page, page.getClass()); 101 bsf.declareBean("cycle", cycle, cycle.getClass()); 102 103 bsf.exec( 104 _language, 105 location.getResource().toString(), 106 location.getLineNumber(), 107 location.getLineNumber(), 108 _script); 109 } 110 catch (BSFException ex) 111 { 112 String message = Tapestry.format("ListenerBinding.bsf-exception", location, ex 113 .getMessage()); 114 115 throw new ApplicationRuntimeException(message, _component, getLocation(), ex); 116 } 117 } 118 119 /** @since 4.0 */ 120 121 public Object getComponent() 122 { 123 return _component; 124 } 125 }