1 package org.apache.velocity.runtime.resource; 2 3 /* 4 * Licensed to the Apache Software Foundation (ASF) under one 5 * or more contributor license agreements. See the NOTICE file 6 * distributed with this work for additional information 7 * regarding copyright ownership. The ASF licenses this file 8 * to you under the Apache License, Version 2.0 (the 9 * "License"); you may not use this file except in compliance 10 * with the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, 15 * software distributed under the License is distributed on an 16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 * KIND, either express or implied. See the License for the 18 * specific language governing permissions and limitations 19 * under the License. 20 */ 21 22 import org.apache.velocity.exception.ParseErrorException; 23 import org.apache.velocity.exception.ResourceNotFoundException; 24 import org.apache.velocity.runtime.RuntimeConstants; 25 import org.apache.velocity.runtime.RuntimeServices; 26 import org.apache.velocity.runtime.resource.loader.ResourceLoader; 27 import org.slf4j.Logger; 28 29 /** 30 * This class represent a general text resource that 31 * may have been retrieved from any number of possible 32 * sources. 33 * 34 * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> 35 * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a> 36 * @version $Id$ 37 */ 38 public abstract class Resource implements Cloneable 39 { 40 protected RuntimeServices rsvc = null; 41 protected Logger log = null; 42 43 /** 44 * The template loader that initially loaded the input 45 * stream for this template, and knows how to check the 46 * source of the input stream for modification. 47 */ 48 protected ResourceLoader resourceLoader; 49 50 /** 51 * The number of milliseconds in a minute, used to calculate the 52 * check interval. 53 */ 54 protected static final long MILLIS_PER_SECOND = 1000; 55 56 /** 57 * How often the file modification time is checked (in seconds). 58 */ 59 protected long modificationCheckInterval = 0; 60 61 /** 62 * The file modification time (in milliseconds) for the cached template. 63 */ 64 protected long lastModified = 0; 65 66 /** 67 * The next time the file modification time will be checked (in 68 * milliseconds). 69 */ 70 protected long nextCheck = 0; 71 72 /** 73 * Name of the resource 74 */ 75 protected String name; 76 77 /** 78 * Character encoding of this resource 79 */ 80 protected String encoding = RuntimeConstants.ENCODING_DEFAULT; 81 82 /** 83 * Resource might require ancillary storage of some kind 84 */ 85 protected Object data = null; 86 87 /** 88 * Resource type (RESOURCE_TEMPLATE or RESOURCE_CONTENT) 89 */ 90 protected int type; 91 92 /** 93 * Default constructor 94 */ Resource()95 public Resource() 96 { 97 } 98 99 /** 100 * @param rs 101 */ setRuntimeServices( RuntimeServices rs )102 public void setRuntimeServices( RuntimeServices rs ) 103 { 104 rsvc = rs; 105 log = rsvc.getLog("loader"); 106 } 107 108 /** 109 * Perform any subsequent processing that might need 110 * to be done by a resource. In the case of a template 111 * the actual parsing of the input stream needs to be 112 * performed. 113 * 114 * @return Whether the resource could be processed successfully. 115 * For a {@link org.apache.velocity.Template} or {@link 116 * org.apache.velocity.runtime.resource.ContentResource}, this 117 * indicates whether the resource could be read. 118 * @exception ResourceNotFoundException Similar in semantics as 119 * returning <code>false</code>. 120 * @throws ParseErrorException 121 */ process()122 public abstract boolean process() 123 throws ResourceNotFoundException, ParseErrorException; 124 125 /** 126 * @return True if source has been modified. 127 */ isSourceModified()128 public boolean isSourceModified() 129 { 130 return resourceLoader.isSourceModified(this); 131 } 132 133 /** 134 * Set the modification check interval. 135 * @param modificationCheckInterval The interval (in seconds). 136 */ setModificationCheckInterval(long modificationCheckInterval)137 public void setModificationCheckInterval(long modificationCheckInterval) 138 { 139 this.modificationCheckInterval = modificationCheckInterval; 140 } 141 142 /** 143 * Is it time to check to see if the resource 144 * source has been updated? 145 * @return True if resource must be checked. 146 */ requiresChecking()147 public boolean requiresChecking() 148 { 149 /* 150 * short circuit this if modificationCheckInterval == 0 151 * as this means "don't check" 152 */ 153 154 if (modificationCheckInterval <= 0 ) 155 { 156 return false; 157 } 158 159 /* 160 * see if we need to check now 161 */ 162 163 return ( System.currentTimeMillis() >= nextCheck ); 164 } 165 166 /** 167 * 'Touch' this template and thereby resetting 168 * the nextCheck field. 169 */ touch()170 public void touch() 171 { 172 nextCheck = System.currentTimeMillis() + ( MILLIS_PER_SECOND * modificationCheckInterval); 173 } 174 175 /** 176 * Set the name of this resource, for example 177 * test.vm. 178 * @param name 179 */ setName(String name)180 public void setName(String name) 181 { 182 this.name = name; 183 } 184 185 /** 186 * Get the name of this template. 187 * @return The name of this template. 188 */ getName()189 public String getName() 190 { 191 return name; 192 } 193 194 /** 195 * set the encoding of this resource 196 * for example, "ISO-8859-1" 197 * @param encoding 198 */ setEncoding( String encoding )199 public void setEncoding( String encoding ) 200 { 201 this.encoding = encoding; 202 } 203 204 /** 205 * get the encoding of this resource 206 * for example, "ISO-8859-1" 207 * @return The encoding of this resource. 208 */ getEncoding()209 public String getEncoding() 210 { 211 return encoding; 212 } 213 214 215 /** 216 * Return the lastModifed time of this 217 * resource. 218 * @return The lastModifed time of this resource. 219 */ getLastModified()220 public long getLastModified() 221 { 222 return lastModified; 223 } 224 225 /** 226 * Set the last modified time for this 227 * resource. 228 * @param lastModified 229 */ setLastModified(long lastModified)230 public void setLastModified(long lastModified) 231 { 232 this.lastModified = lastModified; 233 } 234 235 /** 236 * Return the template loader that pulled 237 * in the template stream 238 * @return The resource loader for this resource. 239 */ getResourceLoader()240 public ResourceLoader getResourceLoader() 241 { 242 return resourceLoader; 243 } 244 245 /** 246 * Set the template loader for this template. Set 247 * when the Runtime determines where this template 248 * came from the list of possible sources. 249 * @param resourceLoader 250 */ setResourceLoader(ResourceLoader resourceLoader)251 public void setResourceLoader(ResourceLoader resourceLoader) 252 { 253 this.resourceLoader = resourceLoader; 254 } 255 256 /** 257 * Set arbitrary data object that might be used 258 * by the resource. 259 * @param data 260 */ setData(Object data)261 public void setData(Object data) 262 { 263 this.data = data; 264 } 265 266 /** 267 * Get arbitrary data object that might be used 268 * by the resource. 269 * @return The data object for this resource. 270 */ getData()271 public Object getData() 272 { 273 return data; 274 } 275 276 /** 277 * Sets the type of this Resource (RESOURCE_TEMPLATE or RESOURCE_CONTENT) 278 * @param type RESOURCE_TEMPLATE or RESOURCE_CONTENT 279 * @since 1.6 280 */ setType(int type)281 public void setType(int type) 282 { 283 this.type = type; 284 } 285 286 /** 287 * @return type code of the Resource 288 * @since 1.6 289 */ getType()290 public int getType() 291 { 292 return type; 293 } 294 295 /** 296 * @return cloned resource 297 * @since 2.4 298 */ 299 @Override clone()300 public Object clone() { 301 try 302 { 303 Resource clone = (Resource) super.clone(); 304 clone.deepCloneData(); 305 return clone; 306 } 307 catch (CloneNotSupportedException e) { 308 throw new RuntimeException("cloning not supported"); 309 } 310 } 311 312 /** 313 * Deep cloning of resource data 314 * @return cloned data 315 */ deepCloneData()316 protected void deepCloneData() throws CloneNotSupportedException 317 { 318 // default implementation does nothing 319 } 320 } 321