Changeset 3472 for trunk

Show
Ignore:
Timestamp:
07/12/07 11:43:16 (4 years ago)
Author:
michael
Message:

Enable setting a custom template factory (to allow refresh setting).

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/main/java/org/sarugo/xtc/impl/DefaultTemplateFactory.java

    r3011 r3472  
    4141public final class DefaultTemplateFactory extends TemplateFactory { 
    4242 
    43         protected final static Logger log = Logger.getLogger("xtc.factory"); 
    44  
    45         private Compiler compiler; 
    46  
    47         private Map templates; 
    48  
    49         private Map relativeLocations; 
    50  
    51         private Resolver resolver; 
    52  
    53         private long refreshPeriod; 
    54  
    55         public DefaultTemplateFactory() throws IOException { 
    56                 this(Compiler.getInstance(), new ClassLoaderResolver()); 
    57         } 
    58  
    59         public DefaultTemplateFactory(Compiler compiler, Resolver resolver) 
    60                         throws IOException { 
    61                 this(compiler, resolver, -1); 
    62         } 
    63  
    64         public DefaultTemplateFactory(Compiler compiler, Resolver resolver, 
    65                         long refreshPeriod) { 
    66                 ParameterCheck.notNull("compiler", compiler); 
    67                 ParameterCheck.notNull("resolver", resolver); 
    68                 this.compiler = compiler; 
    69                 this.templates = new HashMap(); 
    70                 this.relativeLocations = new HashMap(); 
    71                 setResolver(resolver); 
    72                 // this.location = url; 
    73                 log.fine("Using ResourceResolver: " + resolver); 
    74                 this.refreshPeriod = (refreshPeriod > 0) ? refreshPeriod * 1000 : -1; 
    75                 log.fine("Using Refresh Period: " + this.refreshPeriod); 
    76         } 
    77  
    78         public void setResolver(Resolver resolver) { 
    79                 this.resolver = resolver; 
    80         } 
    81  
    82         public Template getTemplate(String uri) throws IOException, 
    83                         TemplateException, ELException { 
    84                 URL url = (URL) this.relativeLocations.get(uri); 
    85                 if (url == null) { 
    86                         url = this.resolveURL(null, uri); 
    87                         if (url != null) { 
    88                                 this.relativeLocations.put(uri, url); 
    89                         } else { 
    90                                 throw new IOException("'" + uri + "' not found."); 
    91                         } 
    92                 } 
    93                 return this.getTemplate(url); 
    94         } 
    95  
    96         /** 
    97          * Resolves a path based on the passed URL. If the path starts with '/', 
    98          * then resolve the path against 
    99          * {@link javax.faces.context.ExternalContext#getResource(java.lang.String) javax.faces.context.ExternalContext#getResource(java.lang.String)}. 
    100          * Otherwise create a new URL via 
    101          * {@link URL#URL(java.net.URL, java.lang.String) URL(URL, String)}. 
    102          *  
    103          * @param source 
    104          *            base to resolve from 
    105          * @param path 
    106          *            relative path to the source 
    107          * @return resolved URL 
    108          * @throws IOException 
    109          */ 
    110         public URL resolveURL(URL source, String path) throws IOException { 
    111                 if (path.startsWith("/")) { 
    112                         URL url = this.resolver.resolveUrl(path); 
    113                         if (url == null) { 
    114                                 throw new FileNotFoundException(path 
    115                                                 + " Not Found in ExternalContext as a Resource"); 
    116                         } 
    117                         return url; 
    118                 } else { 
    119                         return new URL(source, path); 
    120                 } 
    121         } 
    122  
    123         /** 
    124          * Create a Template from the passed URL. This method checks if the cached 
    125          * Template needs to be refreshed before returning. If so, uses the passed 
    126          * URL to build a new instance; 
    127          *  
    128          * @param url 
    129          *            source url 
    130          * @return Template instance 
    131          * @throws IOException 
    132          * @throws TemplateException 
    133          * @throws ELException 
    134          */ 
    135         protected Template getTemplate(URL url) throws IOException, 
    136                         TemplateException, ELException { 
    137                 ParameterCheck.notNull("url", url); 
    138                 DefaultTemplate f = (DefaultTemplate) this.templates.get(url); 
    139                 if (f == null || this.needsToBeRefreshed(f)) { 
    140                         f = this.createTemplate(url); 
    141                         this.templates.put(url, f); 
    142                 } 
    143                 return f; 
    144         } 
    145  
    146         /** 
    147          * Template method for determining if the Template needs to be refreshed. 
    148          *  
    149          * @param template 
    150          *            Template that could have expired 
    151          * @return true if it needs to be refreshed 
    152          */ 
    153         protected boolean needsToBeRefreshed(DefaultTemplate template) 
    154                         throws TemplateException { 
    155                 if (this.refreshPeriod != -1) { 
    156                         long ttl = template.getCreateTime() + this.refreshPeriod; 
    157                         if (System.currentTimeMillis() > ttl) { 
    158                                 try { 
    159                                         long atl = template.getSource().openConnection() 
    160                                                         .getLastModified(); 
    161                                         return atl > ttl; 
    162                                 } catch (Exception e) { 
    163                                         throw new TemplateException( 
    164                                                         "Error Checking Last Modified for " 
    165                                                                         + template.getAlias(), e); 
    166                                 } 
    167                         } 
    168                 } 
    169                 return false; 
    170         } 
    171  
    172         /** 
    173          * Uses the internal Compiler reference to build a Template given the passed 
    174          * URL. 
    175          *  
    176          * @param url 
    177          *            source 
    178          * @return a Template instance 
    179          * @throws IOException 
    180          * @throws TemplateException 
    181          * @throws ELException 
    182          */ 
    183         private DefaultTemplate createTemplate(URL url) throws IOException, 
    184                         TemplateException, ELException { 
    185                 if (log.isLoggable(Level.FINE)) { 
    186                         log.fine("Creating Template for: " + url); 
    187                 } 
    188                 String alias = url.toString(); 
    189                 try { 
    190                         TemplateHandler h = this.compiler.compile(url, alias); 
    191                         DefaultTemplate f = new DefaultTemplate(this, this.compiler 
    192                                         .createExpressionFactory(), url, alias, h); 
    193                         return f; 
    194                 } catch (FileNotFoundException fnfe) { 
    195                         if (log.isLoggable(Level.WARNING)) { 
    196                                 log.warning(alias + " not found at " + url.toExternalForm()); 
    197                         } 
    198                         throw new FileNotFoundException("Template Not Found: " 
    199                                         + url.toExternalForm()); 
    200                 } 
    201         } 
    202  
    203         /** 
    204          * Compiler this factory uses 
    205          *  
    206          * @return final Compiler instance 
    207          */ 
    208         public Compiler getCompiler() { 
    209                 return this.compiler; 
    210         } 
    211  
    212         public long getRefreshPeriod() { 
    213                 return refreshPeriod; 
    214         } 
     43    protected final static Logger log = Logger.getLogger("xtc.factory"); 
     44 
     45    private Compiler compiler; 
     46 
     47    private Map templates; 
     48 
     49    private Map relativeLocations; 
     50 
     51    private Resolver resolver; 
     52 
     53    private long refreshPeriod; 
     54 
     55    public DefaultTemplateFactory() throws IOException { 
     56        this(Compiler.getInstance(), new ClassLoaderResolver()); 
     57    } 
     58 
     59    public DefaultTemplateFactory(Compiler compiler, Resolver resolver) 
     60            throws IOException { 
     61        this(compiler, resolver, -1); 
     62    } 
     63 
     64    public DefaultTemplateFactory(Compiler compiler, Resolver resolver, 
     65            long refreshPeriod) { 
     66        ParameterCheck.notNull("compiler", compiler); 
     67        ParameterCheck.notNull("resolver", resolver); 
     68        this.compiler = compiler; 
     69        this.templates = new HashMap(); 
     70        this.relativeLocations = new HashMap(); 
     71        setResolver(resolver); 
     72        // this.location = url; 
     73        log.fine("Using ResourceResolver: " + resolver); 
     74        this.refreshPeriod = (refreshPeriod > 0) ? refreshPeriod * 1000 : -1; 
     75        log.fine("Using Refresh Period: " + this.refreshPeriod); 
     76    } 
     77 
     78    public void setResolver(Resolver resolver) { 
     79        this.resolver = resolver; 
     80    } 
     81 
     82    public Template getTemplate(String uri) throws IOException, 
     83            TemplateException, ELException { 
     84        URL url = (URL) this.relativeLocations.get(uri); 
     85        if (url == null) { 
     86            url = this.resolveURL(null, uri); 
     87            if (url != null) { 
     88                this.relativeLocations.put(uri, url); 
     89            } else { 
     90                throw new IOException("'" + uri + "' not found."); 
     91            } 
     92        } 
     93        return this.getTemplate(url); 
     94    } 
     95 
     96    /** 
     97     * Resolves a path based on the passed URL. If the path starts with '/', 
     98     * then resolve the path against 
     99     * {@link javax.faces.context.ExternalContext#getResource(java.lang.String) javax.faces.context.ExternalContext#getResource(java.lang.String)}. 
     100     * Otherwise create a new URL via 
     101     * {@link URL#URL(java.net.URL, java.lang.String) URL(URL, String)}. 
     102     *  
     103     * @param source 
     104     *            base to resolve from 
     105     * @param path 
     106     *            relative path to the source 
     107     * @return resolved URL 
     108     * @throws IOException 
     109     */ 
     110    public URL resolveURL(URL source, String path) throws IOException { 
     111        if (path.startsWith("/")) { 
     112            URL url = this.resolver.resolveUrl(path); 
     113            if (url == null) { 
     114                throw new FileNotFoundException(path 
     115                        + " Not Found in ExternalContext as a Resource"); 
     116            } 
     117            return url; 
     118        } else { 
     119            return new URL(source, path); 
     120        } 
     121    } 
     122 
     123    /** 
     124     * Create a Template from the passed URL. This method checks if the cached 
     125     * Template needs to be refreshed before returning. If so, uses the passed 
     126     * URL to build a new instance; 
     127     *  
     128     * @param url 
     129     *            source url 
     130     * @return Template instance 
     131     * @throws IOException 
     132     * @throws TemplateException 
     133     * @throws ELException 
     134     */ 
     135    protected Template getTemplate(URL url) throws IOException, 
     136            TemplateException, ELException { 
     137        ParameterCheck.notNull("url", url); 
     138        DefaultTemplate f = (DefaultTemplate) this.templates.get(url); 
     139        if (f == null || this.needsToBeRefreshed(f)) { 
     140            f = this.createTemplate(url); 
     141            this.templates.put(url, f); 
     142        } 
     143        return f; 
     144    } 
     145 
     146    /** 
     147     * Template method for determining if the Template needs to be refreshed. 
     148     *  
     149     * @param template 
     150     *            Template that could have expired 
     151     * @return true if it needs to be refreshed 
     152     */ 
     153    protected boolean needsToBeRefreshed(DefaultTemplate template) 
     154            throws TemplateException { 
     155        if (this.refreshPeriod != -1) { 
     156            long ttl = template.getCreateTime() + this.refreshPeriod; 
     157            if (System.currentTimeMillis() > ttl) { 
     158                try { 
     159                    long atl = template.getSource().openConnection() 
     160                            .getLastModified(); 
     161                    return atl > ttl; 
     162                } catch (Exception e) { 
     163                    throw new TemplateException( 
     164                            "Error Checking Last Modified for " 
     165                                    + template.getAlias(), e); 
     166                } 
     167            } 
     168        } 
     169        return false; 
     170    } 
     171 
     172    /** 
     173     * Uses the internal Compiler reference to build a Template given the passed 
     174     * URL. 
     175     *  
     176     * @param url 
     177     *            source 
     178     * @return a Template instance 
     179     * @throws IOException 
     180     * @throws TemplateException 
     181     * @throws ELException 
     182     */ 
     183    private DefaultTemplate createTemplate(URL url) throws IOException, 
     184            TemplateException, ELException { 
     185        if (log.isLoggable(Level.FINE)) { 
     186            log.fine("Creating Template for: " + url); 
     187        } 
     188        String alias = url.toString(); 
     189        try { 
     190            TemplateHandler h = this.compiler.compile(url, alias); 
     191            DefaultTemplate f = new DefaultTemplate(this, this.compiler 
     192                    .createExpressionFactory(), url, alias, h); 
     193            return f; 
     194        } catch (FileNotFoundException fnfe) { 
     195            if (log.isLoggable(Level.WARNING)) { 
     196                log.warning(alias + " not found at " + url.toExternalForm()); 
     197            } 
     198            throw new FileNotFoundException("Template Not Found: " 
     199                    + url.toExternalForm()); 
     200        } 
     201    } 
     202 
     203    /** 
     204     * Compiler this factory uses 
     205     *  
     206     * @return final Compiler instance 
     207     */ 
     208    public Compiler getCompiler() { 
     209        return this.compiler; 
     210    } 
     211 
     212    public long getRefreshPeriod() { 
     213        return refreshPeriod; 
     214    } 
     215 
     216    public void setRefreshPeriod(long refreshPeriod) { 
     217        this.refreshPeriod = refreshPeriod; 
     218    } 
    215219} 
  • trunk/src/main/java/org/sarugo/xtc/restlet/TemplateDirectory.java

    r2942 r3472  
    2626import org.restlet.data.Response; 
    2727import org.restlet.resource.Resource; 
     28import org.sarugo.xtc.TemplateFactory; 
    2829/** 
    2930 * {@link Directory} implementation which uses 
     
    5657 */ 
    5758public class TemplateDirectory extends Directory { 
     59     
     60    private TemplateFactory templateFactory; 
    5861 
    5962        public TemplateDirectory(Context context, LocalReference rootLocalReference) { 
    6063                super(context, rootLocalReference); 
     64        templateFactory = TemplateFactory.getInstance(); 
    6165        } 
    6266 
    6367        public TemplateDirectory(Context context, String rootUri) { 
    6468                super(context, rootUri); 
     69        templateFactory = TemplateFactory.getInstance(); 
    6570        } 
    6671 
     
    7681        } 
    7782 
     83    public TemplateFactory getTemplateFactory() { 
     84        return templateFactory; 
     85    } 
     86 
     87    public void setTemplateFactory(TemplateFactory templateFactory) { 
     88        this.templateFactory = templateFactory; 
     89    } 
     90 
    7891} 
  • trunk/src/main/java/org/sarugo/xtc/restlet/TemplateDirectoryResource.java

    r2942 r3472  
    2525import javax.el.ELException; 
    2626 
    27 import org.restlet.Directory; 
    2827import org.restlet.data.MediaType; 
    2928import org.restlet.data.Parameter; 
     
    3534import org.sarugo.xtc.Template; 
    3635import org.sarugo.xtc.TemplateException; 
    37 import org.sarugo.xtc.TemplateFactory; 
    3836 
    3937import com.noelios.restlet.local.DirectoryResource; 
     
    5048public class TemplateDirectoryResource extends DirectoryResource { 
    5149 
    52        public TemplateDirectoryResource(Directory directory, Request request
    53                        Response response) throws IOException { 
    54                super(directory, request, response); 
    55        
     50    public TemplateDirectoryResource(TemplateDirectory directory
     51            Request request, Response response) throws IOException { 
     52        super(directory, request, response); 
     53   
    5654 
    57        /** 
    58         * Invokes {@link DirectoryResource#getVariants()} then if the media type is 
    59         * {@link MediaType.APPLICATION_XHTML_XML}, updates the response to contain 
    60         * a {@link TemplateRepresentation} of the file. 
    61         * <p> 
    62         * The contents of the Request attributes are added to the XTC context and 
    63         * are available to the template. The Request object itself is added with 
    64         * the name <code>request</code>. 
    65         */ 
    66        @Override 
    67        public List<Variant> getVariants() { 
    68                List<Variant> variants = super.getVariants(); 
    69                List<Variant> result = new ArrayList<Variant>(variants.size()); 
    70                for (Variant variant : variants) { 
    71                        if (variant instanceof FileRepresentation 
    72                                        && variant.getMediaType().equals( 
    73                                                        MediaType.APPLICATION_XHTML_XML)) { 
    74                                try { 
    75                                        Template template = TemplateFactory.getInstance(
    76                                                        .getTemplate(getTargetUri()); 
    77                                        TemplateRepresentation representation = new TemplateRepresentation( 
    78                                                        template, variant.getMediaType()); 
    79                                        // Add the request query parameters to the XTC context 
    80                                        for (Parameter param : getRequest().getResourceRef() 
    81                                                        .getQueryAsForm()) { 
    82                                                representation.setVariable(param.getName(), param 
    83                                                                .getValue()); 
    84                                        
    85                                        // Add the request attributes to the XTC context 
    86                                        for (Map.Entry<String, Object> attribute : getRequest() 
    87                                                        .getAttributes().entrySet()) { 
    88                                                representation.setVariable(attribute.getKey(), 
    89                                                                attribute.getValue()); 
    90                                        
    91                                        // Add the request to the XTC context 
    92                                        representation.setVariable("request", getRequest()); 
     55    /** 
     56    * Invokes {@link DirectoryResource#getVariants()} then if the media type is 
     57    * {@link MediaType.APPLICATION_XHTML_XML}, updates the response to contain 
     58    * a {@link TemplateRepresentation} of the file. 
     59    * <p> 
     60    * The contents of the Request attributes are added to the XTC context and 
     61    * are available to the template. The Request object itself is added with 
     62    * the name <code>request</code>. 
     63    */ 
     64    @Override 
     65    public List<Variant> getVariants() { 
     66        List<Variant> variants = super.getVariants(); 
     67        List<Variant> result = new ArrayList<Variant>(variants.size()); 
     68        for (Variant variant : variants) { 
     69            if (variant instanceof FileRepresentation 
     70                    && variant.getMediaType().equals( 
     71                            MediaType.APPLICATION_XHTML_XML)) { 
     72                try { 
     73                    Template template = ((TemplateDirectory) getDirectory()
     74                            .getTemplateFactory().getTemplate(getTargetUri()); 
     75                    TemplateRepresentation representation = new TemplateRepresentation( 
     76                            template, variant.getMediaType()); 
     77                    // Add the request query parameters to the XTC context 
     78                    for (Parameter param : getRequest().getResourceRef() 
     79                            .getQueryAsForm()) { 
     80                        representation.setVariable(param.getName(), param 
     81                                .getValue()); 
     82                   
     83                    // Add the request attributes to the XTC context 
     84                    for (Map.Entry<String, Object> attribute : getRequest() 
     85                            .getAttributes().entrySet()) { 
     86                        representation.setVariable(attribute.getKey(), 
     87                                attribute.getValue()); 
     88                   
     89                    // Add the request to the XTC context 
     90                    representation.setVariable("request", getRequest()); 
    9391 
    94                                        result.add(representation); 
    95                                } catch (TemplateException e) { 
    96                                        getLogger().log(Level.WARNING, 
    97                                                        "Unable to process template file", e); 
    98                                        getResponse().setStatus( 
    99                                                        new Status(Status.SERVER_ERROR_INTERNAL, 
    100                                                                        "Unable to process template file")); 
    101                                } catch (ELException e) { 
    102                                        getLogger().log(Level.WARNING, 
    103                                                        "Unable to process template file", e); 
    104                                        getResponse().setStatus( 
    105                                                        new Status(Status.SERVER_ERROR_INTERNAL, 
    106                                                                        "Unable to process template file")); 
    107                                } catch (IOException e) { 
    108                                        getLogger().log(Level.WARNING, 
    109                                                        "Unable to process template file", e); 
    110                                        getResponse().setStatus( 
    111                                                        new Status(Status.SERVER_ERROR_INTERNAL, 
    112                                                                        "Unable to process template file")); 
    113                                
    114                        } else { 
    115                                result.add(variant); 
    116                        
    117                
    118                return result; 
    119        
     92                    result.add(representation); 
     93                } catch (TemplateException e) { 
     94                    getLogger().log(Level.WARNING, 
     95                            "Unable to process template file", e); 
     96                    getResponse().setStatus( 
     97                            new Status(Status.SERVER_ERROR_INTERNAL, 
     98                                    "Unable to process template file")); 
     99                } catch (ELException e) { 
     100                    getLogger().log(Level.WARNING, 
     101                            "Unable to process template file", e); 
     102                    getResponse().setStatus( 
     103                            new Status(Status.SERVER_ERROR_INTERNAL, 
     104                                    "Unable to process template file")); 
     105                } catch (IOException e) { 
     106                    getLogger().log(Level.WARNING, 
     107                            "Unable to process template file", e); 
     108                    getResponse().setStatus( 
     109                            new Status(Status.SERVER_ERROR_INTERNAL, 
     110                                    "Unable to process template file")); 
     111               
     112            } else { 
     113                result.add(variant); 
     114           
     115       
     116        return result; 
     117   
    120118}