问题的提出: 默认Tapestry的页面模板文件(.Html)及其对应的规范文件(.page),可以放在web根目录或其下的WEB-INF/目录中,Tapestry可以不用任何配置(在以前的版本中需要在.application文件中定义一下页面)就能正确运行,假如你需要在这些根目录下以文件系统的目录形式组织你的页面,则Tapestry是不会自动搜索这些子目录的,你必须在.application文件中定义这些不在默认位置的页面。这样一来,每加一个页面都需要定义一下,假如页面数目众多,定义起来就会比较麻烦,如何才能避免这些配置呢?本文的目的就是尝试解决这个问题。 问题的解决: 本文是在参考文档(http://www.behindthesite.com/blog/C1931765677/E381917869/index.html)源代码的基础上稍作修改而成,主要是为了解决不能在Tomcat中使用的问题。为了更好的了解,朋友们最好能阅读一下原文和原来的代码。主要修改的地方是给RecursiveFileLocator传递一个真实路径地址,以便能够列出目录下面的子目录,从而实现层次查找。 解决的途径就是定义一个ISpecificationResolverDelegate,以便Tapestry在常规路径下找不到文件时进行处理。 CustomSpecificationResolver.Java: // CustomSpecificationResolver.java // // Copyright 2004 Michael J. Henderson & Associates LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may oBTain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either eXPress or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.mjhenderson.users.tapestry; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.tapestry.INamespace; import org.apache.tapestry.IRequestCycle; import org.apache.tapestry.IResourceLocation; import org.apache.tapestry.Tapestry; import org.apache.tapestry.engine.ISpecificationSource; import org.apache.tapestry.resolver.ISpecificationResolverDelegate; import org.apache.tapestry.spec.IComponentSpecification; /** * @author <a href="mailto:michaelh@mjhenderson.com?subject=com.mjhenderson.users.tapestry.CustomSpecificationResolver">Mike Henderson</a> * */ public class CustomSpecificationResolver implements ISpecificationResolverDelegate { private static final Log LOG = LogFactory.getLog(RecursiveFileLocator.class); private ISpecificationSource _specificationSource; private RecursiveFileLocator _locator; //private boolean _applicationIsExplodedWAR; private boolean _initialized; private String _folder; private String _realRootFolder; public CustomSpecificationResolver() {; } public void setFolder(String value) { _folder = value; } public String getFolder() { return _folder; } private void _init(IRequestCycle cycle) { //IResourceLocation rootLocation = Tapestry.getApplicationRootLocation(cycle).getRelativeLocation("/WEB-INF/"); IResourceLocation rootLocation = Tapestry.getApplicationRootLocation(cycle).getRelativeLocation("/"); //_applicationIsExplodedWAR = rootLocation.getResourceURL().toString().startsWith("file:"); //if (_applicationIsExplodedWAR) { _realRootFolder = cycle.getRequestContext().getServlet().getServletContext().getRealPath("/"); _locator = new RecursiveFileLocator(rootLocation,_realRootFolder); _specificationSource = cycle.getEngine().getSpecificationSource(); //} _initialized = true; } // private boolean checkLocationIsFileLocation(IResourceLocation location) { // String url = location.getResourceURL().toString(); // System.out.println("url = "+url); // return url.startsWith("file:"); // } /** * @see org.apache.tapestry.resolver.ISpecificationResolverDelegate#findPageSpecification(org.apache.tapestry.IRequestCycle, org.apache.tapestry.INamespace, java.lang.String) */ public IComponentSpecification findPageSpecification(IRequestCycle cycle, INamespace namespace, String name) { if (!_initialized) { _init(cycle); } //if (!_applicationIsExplodedWAR) { // return null; //} IResourceLocation location = _locator.resolveLocation(name+".page"); if (location != null) { return _specificationSource.getPageSpecification(location); } return null; } /** * @see org.apache.tapestry.resolver.ISpecificationResolverDelegate#findComponentSpecification(org.apache.tapestry.IRequestCycle, org.apache.tapestry.INamespace, java.lang.String) */ public IComponentSpecification findComponentSpecification( IRequestCycle cycle, INamespace namespace, String type) { if (!_initialized) { _init(cycle); } //if (!_applicationIsExplodedWAR) { // return null; //} IResourceLocation location = _locator.resolveLocation(type+".jwc"); if (location != null) { return _specificationSource.getComponentSpecification(location); } return null; } } RecursiveFileLocator.java: // RecursiveFileLocator.java // // Copyright 2004 Michael J. Henderson & Associates LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.mjhenderson.users.tapestry; import java.io.File; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.tapestry.IResourceLocation; /** * @author <a href="mailto:michaelh@mjhenderson.com?subject=com.mjhenderson.users.tapestry.RecursiveFileLocator">Mike Henderson</a> * */ public class RecursiveFileLocator { private static final Log LOG = LogFactory.getLog(RecursiveFileLocator.class); private IResourceLocation _location; private File realRoot ; private Map _locations = new HashMap(); public RecursiveFileLocator(IResourceLocation location,String _realRootFolder) { realRoot = new
|