Search in sources :

Example 1 with BugException

use of freemarker.core.BugException in project freemarker by apache.

the class TemplateCache method getTemplateInternal.

private Template getTemplateInternal(final String name, final Locale locale, final Object customLookupCondition, final String encoding, final boolean parseAsFTL) throws IOException {
    final boolean debug = LOG.isDebugEnabled();
    final String debugName = debug ? buildDebugName(name, locale, customLookupCondition, encoding, parseAsFTL) : null;
    final TemplateKey tk = new TemplateKey(name, locale, customLookupCondition, encoding, parseAsFTL);
    CachedTemplate cachedTemplate;
    if (isStorageConcurrent) {
        cachedTemplate = (CachedTemplate) storage.get(tk);
    } else {
        synchronized (storage) {
            cachedTemplate = (CachedTemplate) storage.get(tk);
        }
    }
    final long now = System.currentTimeMillis();
    long lastModified = -1L;
    boolean rethrown = false;
    TemplateLookupResult newLookupResult = null;
    try {
        if (cachedTemplate != null) {
            // If we're within the refresh delay, return the cached copy
            if (now - cachedTemplate.lastChecked < updateDelay) {
                if (debug) {
                    LOG.debug(debugName + " cached copy not yet stale; using cached.");
                }
                // Can be null, indicating a cached negative lookup
                Object t = cachedTemplate.templateOrException;
                if (t instanceof Template || t == null) {
                    return (Template) t;
                } else if (t instanceof RuntimeException) {
                    throwLoadFailedException((RuntimeException) t);
                } else if (t instanceof IOException) {
                    rethrown = true;
                    throwLoadFailedException((IOException) t);
                }
                throw new BugException("t is " + t.getClass().getName());
            }
            // Clone as the instance bound to the map should be treated as
            // immutable to ensure proper concurrent semantics
            cachedTemplate = cachedTemplate.cloneCachedTemplate();
            // Update the last-checked flag
            cachedTemplate.lastChecked = now;
            // Find the template source
            newLookupResult = lookupTemplate(name, locale, customLookupCondition);
            // Template source was removed
            if (!newLookupResult.isPositive()) {
                if (debug) {
                    LOG.debug(debugName + " no source found.");
                }
                storeNegativeLookup(tk, cachedTemplate, null);
                return null;
            }
            // If the source didn't change and its last modified date
            // also didn't change, return the cached version.
            final Object newLookupResultSource = newLookupResult.getTemplateSource();
            lastModified = templateLoader.getLastModified(newLookupResultSource);
            boolean lastModifiedNotChanged = lastModified == cachedTemplate.lastModified;
            boolean sourceEquals = newLookupResultSource.equals(cachedTemplate.source);
            if (lastModifiedNotChanged && sourceEquals) {
                if (debug) {
                    LOG.debug(debugName + ": using cached since " + newLookupResultSource + " hasn't changed.");
                }
                storeCached(tk, cachedTemplate);
                return (Template) cachedTemplate.templateOrException;
            } else if (debug) {
                if (!sourceEquals) {
                    LOG.debug("Updating source because: " + "sourceEquals=" + sourceEquals + ", newlyFoundSource=" + StringUtil.jQuoteNoXSS(newLookupResultSource) + ", cached.source=" + StringUtil.jQuoteNoXSS(cachedTemplate.source));
                } else if (!lastModifiedNotChanged) {
                    LOG.debug("Updating source because: " + "lastModifiedNotChanged=" + lastModifiedNotChanged + ", cached.lastModified=" + cachedTemplate.lastModified + " != source.lastModified=" + lastModified);
                }
            }
        } else {
            if (debug) {
                LOG.debug("Couldn't find template in cache for " + debugName + "; will try to load it.");
            }
            // Construct a new CachedTemplate entry. Note we set the
            // cachedTemplate.lastModified to Long.MIN_VALUE. This is
            // a flag that signs it has to be explicitly queried later on.
            cachedTemplate = new CachedTemplate();
            cachedTemplate.lastChecked = now;
            newLookupResult = lookupTemplate(name, locale, customLookupCondition);
            if (!newLookupResult.isPositive()) {
                storeNegativeLookup(tk, cachedTemplate, null);
                return null;
            }
            cachedTemplate.lastModified = lastModified = Long.MIN_VALUE;
        }
        Object source = newLookupResult.getTemplateSource();
        cachedTemplate.source = source;
        // If we get here, then we need to (re)load the template
        if (debug) {
            LOG.debug("Loading template for " + debugName + " from " + StringUtil.jQuoteNoXSS(source));
        }
        lastModified = lastModified == Long.MIN_VALUE ? templateLoader.getLastModified(source) : lastModified;
        Template template = loadTemplate(templateLoader, source, name, newLookupResult.getTemplateSourceName(), locale, customLookupCondition, encoding, parseAsFTL);
        cachedTemplate.templateOrException = template;
        cachedTemplate.lastModified = lastModified;
        storeCached(tk, cachedTemplate);
        return template;
    } catch (RuntimeException e) {
        if (cachedTemplate != null) {
            storeNegativeLookup(tk, cachedTemplate, e);
        }
        throw e;
    } catch (IOException e) {
        if (!rethrown) {
            storeNegativeLookup(tk, cachedTemplate, e);
        }
        throw e;
    } finally {
        if (newLookupResult != null && newLookupResult.isPositive()) {
            templateLoader.closeTemplateSource(newLookupResult.getTemplateSource());
        }
    }
}
Also used : IOException(java.io.IOException) BugException(freemarker.core.BugException) Template(freemarker.template.Template)

Example 2 with BugException

use of freemarker.core.BugException in project freemarker by apache.

the class TaglibFactory method get.

/**
 * Retrieves a JSP tag library identified by an URI. The matching of the URI to a JSP taglib is done as described in
 * the JSP 1.2 FCS specification.
 *
 * @param taglibUri
 *            The URI used in templates to refer to the taglib (like {@code <%@ taglib uri="..." ... %>} in
 *            JSP). It can be any of the three forms allowed by the JSP specification: absolute URI (like
 *            {@code http://example.com/foo}), root relative URI (like {@code /bar/foo.tld}) and non-root relative
 *            URI (like {@code bar/foo.tld}). Note that if a non-root relative URI is used it's resolved relative to
 *            the URL of the current request. In this case, the current request is obtained by looking up a
 *            {@link HttpRequestHashModel} object named <tt>Request</tt> in the root data model.
 *            {@link FreemarkerServlet} provides this object under the expected name, and custom servlets that want
 *            to integrate JSP taglib support should do the same.
 *
 * @return a {@link TemplateHashModel} representing the JSP taglib. Each element of this hash represents a single
 *         custom tag or EL function from the library, implemented as a {@link TemplateTransformModel} or
 *         {@link TemplateMethodModelEx}, respectively.
 */
public TemplateModel get(final String taglibUri) throws TemplateModelException {
    synchronized (lock) {
        {
            final Taglib taglib = (Taglib) taglibs.get(taglibUri);
            if (taglib != null) {
                return taglib;
            }
        }
        boolean failedTldListAlreadyIncluded = false;
        final TldLocation tldLocation;
        final String normalizedTaglibUri;
        try {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Locating TLD for taglib URI " + StringUtil.jQuoteNoXSS(taglibUri) + ".");
            }
            TldLocation explicitlyMappedTldLocation = getExplicitlyMappedTldLocation(taglibUri);
            if (explicitlyMappedTldLocation != null) {
                tldLocation = explicitlyMappedTldLocation;
                normalizedTaglibUri = taglibUri;
            } else {
                // Taglib URI must be directly the path (no mapping).
                final int urlType;
                try {
                    urlType = getUriType(taglibUri);
                } catch (MalformedURLException e) {
                    throw new TaglibGettingException("Malformed taglib URI: " + StringUtil.jQuote(taglibUri), e);
                }
                if (urlType == URL_TYPE_RELATIVE) {
                    normalizedTaglibUri = resolveRelativeUri(taglibUri);
                } else if (urlType == URL_TYPE_ABSOLUTE) {
                    normalizedTaglibUri = taglibUri;
                } else if (urlType == URL_TYPE_FULL) {
                    // Per spec., full URI-s can only be resolved through explicit mapping
                    String failedTLDsList = getFailedTLDsList();
                    failedTldListAlreadyIncluded = true;
                    throw new TaglibGettingException("No TLD was found for the " + StringUtil.jQuoteNoXSS(taglibUri) + " JSP taglib URI. (TLD-s are searched according " + "the JSP 2.2 specification. In development- and embedded-servlet-container " + "setups you may also need the " + "\"" + FreemarkerServlet.INIT_PARAM_META_INF_TLD_LOCATIONS + "\" and " + "\"" + FreemarkerServlet.INIT_PARAM_CLASSPATH_TLDS + "\" " + FreemarkerServlet.class.getName() + " init-params or the similar system " + "properites." + (failedTLDsList == null ? "" : " Also note these TLD-s were skipped earlier due to errors; " + "see error in the log: " + failedTLDsList) + ")");
                } else {
                    throw new BugException();
                }
                if (!normalizedTaglibUri.equals(taglibUri)) {
                    final Taglib taglib = (Taglib) taglibs.get(normalizedTaglibUri);
                    if (taglib != null) {
                        return taglib;
                    }
                }
                tldLocation = isJarPath(normalizedTaglibUri) ? (TldLocation) new ServletContextJarEntryTldLocation(normalizedTaglibUri, DEFAULT_TLD_RESOURCE_PATH) : (TldLocation) new ServletContextTldLocation(normalizedTaglibUri);
            }
        } catch (Exception e) {
            String failedTLDsList = failedTldListAlreadyIncluded ? null : getFailedTLDsList();
            throw new TemplateModelException("Error while looking for TLD file for " + StringUtil.jQuoteNoXSS(taglibUri) + "; see cause exception." + (failedTLDsList == null ? "" : " (Note: These TLD-s were skipped earlier due to errors; " + "see errors in the log: " + failedTLDsList + ")"), e);
        }
        try {
            return loadTaglib(tldLocation, normalizedTaglibUri);
        } catch (Exception e) {
            throw new TemplateModelException("Error while loading tag library for URI " + StringUtil.jQuoteNoXSS(normalizedTaglibUri) + " from TLD location " + StringUtil.jQuoteNoXSS(tldLocation) + "; see cause exception.", e);
        }
    }
}
Also used : TemplateModelException(freemarker.template.TemplateModelException) MalformedURLException(java.net.MalformedURLException) BugException(freemarker.core.BugException) URISyntaxException(java.net.URISyntaxException) NullArgumentException(freemarker.template.utility.NullArgumentException) ZipException(java.util.zip.ZipException) IntrospectionException(java.beans.IntrospectionException) SAXException(org.xml.sax.SAXException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) TemplateModelException(freemarker.template.TemplateModelException) BugException(freemarker.core.BugException) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException) SAXParseException(org.xml.sax.SAXParseException) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException)

Example 3 with BugException

use of freemarker.core.BugException in project freemarker by apache.

the class BeansWrapper method newInstance.

/**
 * Creates a new instance of the specified class using the method call logic of this object wrapper for calling the
 * constructor. Overloaded constructors and varargs are supported. Only public constructors will be called.
 *
 * @param clazz The class whose constructor we will call.
 * @param arguments The list of {@link TemplateModel}-s to pass to the constructor after unwrapping them
 * @return The instance created; it's not wrapped into {@link TemplateModel}.
 */
public Object newInstance(Class<?> clazz, List arguments) throws TemplateModelException {
    try {
        Object ctors = classIntrospector.get(clazz).get(ClassIntrospector.CONSTRUCTORS_KEY);
        if (ctors == null) {
            throw new TemplateModelException("Class " + clazz.getName() + " has no public constructors.");
        }
        Constructor<?> ctor = null;
        Object[] objargs;
        if (ctors instanceof SimpleMethod) {
            SimpleMethod sm = (SimpleMethod) ctors;
            ctor = (Constructor<?>) sm.getMember();
            objargs = sm.unwrapArguments(arguments, this);
            try {
                return ctor.newInstance(objargs);
            } catch (Exception e) {
                if (e instanceof TemplateModelException)
                    throw (TemplateModelException) e;
                throw _MethodUtil.newInvocationTemplateModelException(null, ctor, e);
            }
        } else if (ctors instanceof OverloadedMethods) {
            final MemberAndArguments mma = ((OverloadedMethods) ctors).getMemberAndArguments(arguments, this);
            try {
                return mma.invokeConstructor(this);
            } catch (Exception e) {
                if (e instanceof TemplateModelException)
                    throw (TemplateModelException) e;
                throw _MethodUtil.newInvocationTemplateModelException(null, mma.getCallableMemberDescriptor(), e);
            }
        } else {
            // Cannot happen
            throw new BugException();
        }
    } catch (TemplateModelException e) {
        throw e;
    } catch (Exception e) {
        throw new TemplateModelException("Error while creating new instance of class " + clazz.getName() + "; see cause exception", e);
    }
}
Also used : TemplateModelException(freemarker.template.TemplateModelException) freemarker.core._TemplateModelException(freemarker.core._TemplateModelException) AccessibleObject(java.lang.reflect.AccessibleObject) BugException(freemarker.core.BugException) InvocationTargetException(java.lang.reflect.InvocationTargetException) TemplateModelException(freemarker.template.TemplateModelException) BugException(freemarker.core.BugException) freemarker.core._TemplateModelException(freemarker.core._TemplateModelException)

Example 4 with BugException

use of freemarker.core.BugException in project freemarker by apache.

the class ClassIntrospector method remove.

/**
 * Corresponds to {@link BeansWrapper#removeFromClassIntrospectionCache(Class)}.
 *
 * @since 2.3.20
 */
void remove(Class<?> clazz) {
    synchronized (sharedLock) {
        cache.remove(clazz);
        cacheClassNames.remove(clazz.getName());
        clearingCounter++;
        for (WeakReference<Object> regedMfREf : modelFactories) {
            Object regedMf = regedMfREf.get();
            if (regedMf != null) {
                if (regedMf instanceof ClassBasedModelFactory) {
                    ((ClassBasedModelFactory) regedMf).removeFromCache(clazz);
                } else if (regedMf instanceof ModelCache) {
                    // doesn't support selective clearing ATM
                    ((ModelCache) regedMf).clearCache();
                } else {
                    throw new BugException();
                }
            }
        }
        removeClearedModelFactoryReferences();
    }
}
Also used : BugException(freemarker.core.BugException) ModelCache(freemarker.ext.util.ModelCache)

Example 5 with BugException

use of freemarker.core.BugException in project freemarker by apache.

the class ClassIntrospector method forcedClearCache.

private void forcedClearCache() {
    synchronized (sharedLock) {
        cache.clear();
        cacheClassNames.clear();
        clearingCounter++;
        for (WeakReference<Object> regedMfREf : modelFactories) {
            Object regedMf = regedMfREf.get();
            if (regedMf != null) {
                if (regedMf instanceof ClassBasedModelFactory) {
                    ((ClassBasedModelFactory) regedMf).clearCache();
                } else if (regedMf instanceof ModelCache) {
                    ((ModelCache) regedMf).clearCache();
                } else {
                    throw new BugException();
                }
            }
        }
        removeClearedModelFactoryReferences();
    }
}
Also used : BugException(freemarker.core.BugException) ModelCache(freemarker.ext.util.ModelCache)

Aggregations

BugException (freemarker.core.BugException)10 IOException (java.io.IOException)4 ModelCache (freemarker.ext.util.ModelCache)2 TemplateModelException (freemarker.template.TemplateModelException)2 NullArgumentException (freemarker.template.utility.NullArgumentException)2 IntrospectionException (java.beans.IntrospectionException)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)2 ParseException (freemarker.core.ParseException)1 ParserConfiguration (freemarker.core.ParserConfiguration)1 TemplateConfiguration (freemarker.core.TemplateConfiguration)1 UnregisteredOutputFormatException (freemarker.core.UnregisteredOutputFormatException)1 freemarker.core._MiscTemplateException (freemarker.core._MiscTemplateException)1 freemarker.core._TemplateModelException (freemarker.core._TemplateModelException)1 Template (freemarker.template.Template)1 IndexedPropertyDescriptor (java.beans.IndexedPropertyDescriptor)1 PropertyDescriptor (java.beans.PropertyDescriptor)1 File (java.io.File)1 StringReader (java.io.StringReader)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 AccessibleObject (java.lang.reflect.AccessibleObject)1