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 }