001 // Copyright 2006, 2008, 2010 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.tapestry5.internal.services; 016 017 import java.io.File; 018 import java.net.MalformedURLException; 019 import java.net.URL; 020 021 import org.apache.tapestry5.ioc.Resource; 022 import org.apache.tapestry5.ioc.internal.util.AbstractResource; 023 import org.apache.tapestry5.services.Context; 024 025 /** 026 * A resource stored with in the web application context. 027 */ 028 public class ContextResource extends AbstractResource 029 { 030 private static final int PRIME = 37; 031 032 private final Context context; 033 034 public ContextResource(Context context, String path) 035 { 036 super(path); 037 038 assert context != null; 039 040 this.context = context; 041 } 042 043 @Override 044 public String toString() 045 { 046 return String.format("context:%s", getPath()); 047 } 048 049 @Override 050 protected Resource newResource(String path) 051 { 052 return new ContextResource(context, path); 053 } 054 055 public URL toURL() 056 { 057 // This is so easy to screw up; ClassLoader.getResource() doesn't want a leading slash, 058 // and HttpServletContext.getResource() does. This is what I mean when I say that 059 // a framework is an accumulation of the combined experience of many users and developers. 060 061 String contextPath = "/" + getPath(); 062 063 // Always prefer the actual file to the URL. This is critical for templates to 064 // reload inside Tomcat. 065 066 File file = context.getRealFile(contextPath); 067 068 if (file != null && file.exists()) 069 { 070 try 071 { 072 return file.toURL(); 073 } 074 catch (MalformedURLException ex) 075 { 076 throw new RuntimeException(ex); 077 } 078 } 079 080 // But, when packaged inside a WAR or JAR, the File will not be available, so use whatever 081 // URL we get ... but reloading won't work. 082 083 return context.getResource(contextPath); 084 } 085 086 @Override 087 public int hashCode() 088 { 089 return PRIME * context.hashCode() + getPath().hashCode(); 090 } 091 092 @Override 093 public boolean equals(Object obj) 094 { 095 if (this == obj) return true; 096 if (obj == null) return false; 097 if (getClass() != obj.getClass()) return false; 098 099 final ContextResource other = (ContextResource) obj; 100 101 return context == other.context && getPath().equals(other.getPath()); 102 } 103 104 }