Bob,

Thank you for the help. I put this in my BasePage class for convenience and it 
works - still have to test in production. My problem was not paying attention 
to the getThreadLocalContext() method.

public boolean resourceExists(String resourceName)
  {
  Context context = Context.getThreadLocalContext();
        
  try
    {
    return context.getServletContext().getResource(resourceName) != null;
    }
  catch (MalformedURLException e)
    {
    e.printStackTrace();
    return false;
    }
  }


On Dec 26, 2010, at 7:00 PM, Bob Schellink wrote:

> Ah, Velocity is trying to log to the file system which isn't allowed in GAE. 
> You can off course read
> files. So perhaps instead of Velocity.resourceExists, use the servletContext 
> Servlet API:
> 
> public static boolean resourceExists(String resourceName) {
>    ServletContext sc = Context.getThreadLocalContext();
>    URL resource = servletContext.getResource(resourceName);
>    return resource != null;
> }
> 
> Kind regards
> 
> Bob
> 
> On 27/12/2010 12:40, Tim Christensen wrote:
>> Bob,
>> 
>> Thank you for taking the time to help out - unfortunately the security 
>> restriction kicks in:
>> 
>> java.security.AccessControlException: access denied (java.io.FilePermission 
>> velocity.log write)
>>      at 
>> java.security.AccessControlContext.checkPermission(AccessControlContext.java:323)
>>      at 
>> java.security.AccessController.checkPermission(AccessController.java:546)
>>      at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
>>      at 
>> com.google.appengine.tools.development.DevAppServerFactory$CustomSecurityManager.checkPermission(DevAppServerFactory.java:166)
>>      at java.lang.SecurityManager.checkWrite(SecurityManager.java:962)
>>      at java.io.FileOutputStream.<init>(FileOutputStream.java:169)
>>      at java.io.FileOutputStream.<init>(FileOutputStream.java:102)
>>      at org.apache.log4j.FileAppender.setFile(FileAppender.java:290)
>>      at 
>> org.apache.log4j.RollingFileAppender.setFile(RollingFileAppender.java:194)
>>      at org.apache.log4j.FileAppender.<init>(FileAppender.java:109)
>>      at 
>> org.apache.log4j.RollingFileAppender.<init>(RollingFileAppender.java:72)
>>      at 
>> org.apache.velocity.runtime.log.Log4JLogChute.initAppender(Log4JLogChute.java:118)
>>      at 
>> org.apache.velocity.runtime.log.Log4JLogChute.init(Log4JLogChute.java:85)
>>      at 
>> org.apache.velocity.runtime.log.LogManager.createLogChute(LogManager.java:157)
>>      at 
>> org.apache.velocity.runtime.log.LogManager.updateLog(LogManager.java:255)
>>      at 
>> org.apache.velocity.runtime.RuntimeInstance.initializeLog(RuntimeInstance.java:795)
>>      at 
>> org.apache.velocity.runtime.RuntimeInstance.init(RuntimeInstance.java:250)
>>      at 
>> org.apache.velocity.runtime.RuntimeInstance.requireInitialization(RuntimeInstance.java:290)
>>      at 
>> org.apache.velocity.runtime.RuntimeInstance.getLoaderNameForResource(RuntimeInstance.java:1462)
>>      at 
>> org.apache.velocity.runtime.RuntimeSingleton.getLoaderNameForResource(RuntimeSingleton.java:380)
>>      at org.apache.velocity.app.Velocity.resourceExists(Velocity.java:423)
>> 
>> 
>> 
>> On Dec 26, 2010, at 5:39 PM, Bob Schellink wrote:
>> 
>>> Hi Tim,
>>> 
>>> Velocity has a way to check if a template/resource exists through this 
>>> static method[1]:
>>> 
>>> Velocity.resourceExists(name);
>>> 
>>> I'm not sure how efficient this check is though as it might touch the file 
>>> system. You could ask on
>>> the Velocity mailing list just to make sure. If it does touch the file 
>>> system it should be easy to
>>> cache it in your app through some utility class:
>>> 
>>> VelocityUtils {
>>> private static Map<String, Integer> CACHE = new ConcurrentHashMap();
>>> 
>>> public boolean resourceExists(String name) {
>>>   int val = CACHE.get(name);
>>>   if (val == 1) {
>>>     return true;
>>>   } else if (val == 0) {
>>>     return false;
>>> } else {
>>>   if(Velocity.resourceExists(name)) {
>>>     CACHE.put(name, 1);
>>>   } else {
>>>           CACHE.put(name, 0);
>>>   }
>>> }
>>> }
>>> 
>>> or something along those lines.
>>> 
>>> Id you are using GAE you should probably use 2.3.0-M1 which provides a 
>>> workaround[2] for a GAE bug
>>> which breaks Page automapping.
>>> 
>>> Hope this helps
>>> 
>>> Kind regards
>>> 
>>> Bob
>>> 
>>> [1]:
>>> http://velocity.apache.org/engine/releases/velocity-1.7/apidocs/org/apache/velocity/app/Velocity.html#resourceExists(java.lang.String)
>>> [2]:
>>> http://click.apache.org/docs/extras-api/org/apache/click/extras/gae/GoogleAppEngineListener.html
>>> (See the Limitations section in the Javadoc)
>>> 
>>> 
>>> On 27/12/2010 10:34, Tim Christensen wrote:
>>>> I am building a web application using Click on the Google App Engine. One 
>>>> of the 'features' I would
>>>> like to have is the ability to try setting a template -- if it is 
>>>> available. Like the Click example
>>>> we have a BasePage > BorderPage (with a template of border.htm) and our 
>>>> Page classes extend
>>>> BorderPage.
>>>> 
>>>> One of those Page classes is BrandPage -- for some consumer brands. The 
>>>> BrandPage will have some
>>>> common methods - search for products matching this brand for example - 
>>>> think ecommerce.
>>>> Additionally, there is a brand.htm file for the BrandPage.
>>>> 
>>>> However, I would like some brands, not all, to have a template available 
>>>> to parse - we would like to
>>>> build out some custom .htm pages to parse in the brand.htm. For example we 
>>>> may have three brands ,
>>>> A, B, C and A.htm, C.htm but not a B.htm in a directory say ... 
>>>> /brand/A.htm
>>>> 
>>>> Normally in the BrandPage I would put something like this:
>>>> 
>>>> public String getTemplate()
>>>> {
>>>> return A.htm (or C.htm, or even B.htm)
>>>> }
>>>> 
>>>> From the example above, while A.htm or C.htm exist, B.htm does not.
>>>> 
>>>> How this would have happened is that when the BrandPage was requested, 
>>>> with a brand id for example,
>>>> the database search would return the brand (and product etc...). I would 
>>>> then 'dynamically' set the
>>>> getTemplate() return to [Normalized Brand Name].htm
>>>> 
>>>> My question is this -- how can I test to see if B.htm exists before I even 
>>>> set the getTemplate
>>>> return value? My focus has been using something utility-wise in Click - am 
>>>> I missing a simple way to
>>>> do this? Wrap a try catch somewhere? As you would expect, I currently get 
>>>> the
>>>> org.apache.velocity.exception.ResourceNotFoundException -- but I cannot 
>>>> catch it in the Page in
>>>> order to do something else.
>>>> 
>>>> I also want it to be a quick process. I have pondered using File to look 
>>>> in a specific directory
>>>> ("/brand/file.htm"). My biggest concerns are: 1. Speed for this 
>>>> 'function', 2. Google App Engine
>>>> restrictions - would looking at a file in the /war cause an issue, and 
>>>> finally if Click has
>>>> something I missed as a convenience for this idea. Solving this gives us 
>>>> tremendous flexibility on
>>>> the presentation and is a critical feature to our application. I am also 
>>>> concerned that the way I am
>>>> thinking about this is flawed so any alternative design pattern 
>>>> suggestions are welcome.
>>>> 
>>>> Thank you for a great framework - I have tried nearly all of them and 
>>>> Click nailed it.
>>>> 
>>> 
>> 



Reply via email to