use of freemarker.core.BugException in project freemarker by apache.
the class ClassIntrospector method getPropertyDescriptors.
/**
* Very similar to {@link BeanInfo#getPropertyDescriptors()}, but can deal with Java 8 default methods too.
*/
private List<PropertyDescriptor> getPropertyDescriptors(BeanInfo beanInfo, Class<?> clazz) {
PropertyDescriptor[] introspectorPDsArray = beanInfo.getPropertyDescriptors();
List<PropertyDescriptor> introspectorPDs = introspectorPDsArray != null ? Arrays.asList(introspectorPDsArray) : Collections.<PropertyDescriptor>emptyList();
if (!treatDefaultMethodsAsBeanMembers || _JavaVersions.JAVA_8 == null) {
// java.beans.Introspector was good enough then.
return introspectorPDs;
}
// introspectorPDs contains each property exactly once. But as now we will search them manually too, it can
// happen that we find the same property for multiple times. Worse, because of indexed properties, it's possible
// that we have to merge entries (like one has the normal reader method, the other has the indexed reader
// method), instead of just replacing them in a Map. That's why we have introduced PropertyReaderMethodPair,
// which holds the methods belonging to the same property name. IndexedPropertyDescriptor is not good for that,
// as it can't store two methods whose types are incompatible, and we have to wait until all the merging was
// done to see if the incompatibility goes away.
// This could be Map<String, PropertyReaderMethodPair>, but since we rarely need to do merging, we try to avoid
// creating those and use the source objects as much as possible. Also note that we initialize this lazily.
LinkedHashMap<String, Object> /*PropertyReaderMethodPair|Method|PropertyDescriptor*/
mergedPRMPs = null;
// here, we don't utilize the accessibleMethods Map, which we might already have at this point.)
for (Method method : clazz.getMethods()) {
if (_JavaVersions.JAVA_8.isDefaultMethod(method) && method.getReturnType() != void.class && !method.isBridge()) {
Class<?>[] paramTypes = method.getParameterTypes();
if (paramTypes.length == 0 || paramTypes.length == 1 && paramTypes[0] == int.class) /* indexed property reader */
{
String propName = _MethodUtil.getBeanPropertyNameFromReaderMethodName(method.getName(), method.getReturnType());
if (propName != null) {
if (mergedPRMPs == null) {
// Lazy initialization
mergedPRMPs = new LinkedHashMap<String, Object>();
}
if (paramTypes.length == 0) {
mergeInPropertyReaderMethod(mergedPRMPs, propName, method);
} else {
// It's an indexed property reader method
mergeInPropertyReaderMethodPair(mergedPRMPs, propName, new PropertyReaderMethodPair(null, method));
}
}
}
}
}
if (mergedPRMPs == null) {
// We had no interfering Java 8 default methods, so we can chose the fast route.
return introspectorPDs;
}
for (PropertyDescriptor introspectorPD : introspectorPDs) {
mergeInPropertyDescriptor(mergedPRMPs, introspectorPD);
}
// Now we convert the PRMPs to PDs, handling case where the normal and the indexed read methods contradict.
List<PropertyDescriptor> mergedPDs = new ArrayList<PropertyDescriptor>(mergedPRMPs.size());
for (Entry<String, Object> entry : mergedPRMPs.entrySet()) {
String propName = entry.getKey();
Object propDescObj = entry.getValue();
if (propDescObj instanceof PropertyDescriptor) {
mergedPDs.add((PropertyDescriptor) propDescObj);
} else {
Method readMethod;
Method indexedReadMethod;
if (propDescObj instanceof Method) {
readMethod = (Method) propDescObj;
indexedReadMethod = null;
} else if (propDescObj instanceof PropertyReaderMethodPair) {
PropertyReaderMethodPair prmp = (PropertyReaderMethodPair) propDescObj;
readMethod = prmp.readMethod;
indexedReadMethod = prmp.indexedReadMethod;
if (readMethod != null && indexedReadMethod != null && indexedReadMethod.getReturnType() != readMethod.getReturnType().getComponentType()) {
// Here we copy the java.beans.Introspector behavior: If the array item class is not exactly the
// the same as the indexed read method return type, we say that the property is not indexed.
indexedReadMethod = null;
}
} else {
throw new BugException();
}
try {
mergedPDs.add(indexedReadMethod != null ? new IndexedPropertyDescriptor(propName, readMethod, null, indexedReadMethod, null) : new PropertyDescriptor(propName, readMethod, null));
} catch (IntrospectionException e) {
if (LOG.isWarnEnabled()) {
LOG.warn("Failed creating property descriptor for " + clazz.getName() + " property " + propName, e);
}
}
}
}
return mergedPDs;
}
use of freemarker.core.BugException in project freemarker by apache.
the class Template method getPlainTextTemplate.
/**
* Creates (not "get"-s) a {@link Template} that only contains a single block of static text, no dynamic content.
*
* @param name
* See {@link #getName} for more details.
* @param sourceName
* See {@link #getSourceName} for more details. If {@code null}, it will be the same as the {@code name}.
* @param content
* the block of text that this template represents
* @param config
* the configuration to which this template belongs
*
* @since 2.3.22
*/
public static Template getPlainTextTemplate(String name, String sourceName, String content, Configuration config) {
Template template;
try {
template = new Template(name, sourceName, new StringReader("X"), config);
} catch (IOException e) {
throw new BugException("Plain text template creation failed", e);
}
_CoreAPI.replaceText((TextBlock) template.rootElement, content);
DebuggerService.registerTemplate(template);
return template;
}
use of freemarker.core.BugException in project freemarker by apache.
the class Configuration method clone.
@Override
public Object clone() {
try {
Configuration copy = (Configuration) super.clone();
copy.sharedVariables = new HashMap(sharedVariables);
copy.localeToCharsetMap = new ConcurrentHashMap(localeToCharsetMap);
copy.recreateTemplateCacheWith(cache.getTemplateLoader(), cache.getCacheStorage(), cache.getTemplateLookupStrategy(), cache.getTemplateNameFormat(), cache.getTemplateConfigurations());
return copy;
} catch (CloneNotSupportedException e) {
throw new BugException("Cloning failed", e);
}
}
use of freemarker.core.BugException in project freemarker by apache.
the class Configuration method setServletContextForTemplateLoading.
/**
* Sets the servlet context from which to load templates.
* This is equivalent to {@code setTemplateLoader(new WebappTemplateLoader(sctxt, path))}
* or {@code setTemplateLoader(new WebappTemplateLoader(sctxt))} if {@code path} was
* {@code null}, so see {@code freemarker.cache.WebappTemplateLoader} for more details.
*
* @param servletContext the {@code javax.servlet.ServletContext} object. (The declared type is {@link Object}
* to prevent class loading error when using FreeMarker in an environment where
* there's no servlet classes available.)
* @param path the path relative to the ServletContext.
*
* @see #setTemplateLoader(TemplateLoader)
*/
public void setServletContextForTemplateLoading(Object servletContext, String path) {
try {
// Don't introduce linking-time dependency on servlets
final Class webappTemplateLoaderClass = ClassUtil.forName("freemarker.cache.WebappTemplateLoader");
// Don't introduce linking-time dependency on servlets
final Class servletContextClass = ClassUtil.forName("javax.servlet.ServletContext");
final Class[] constructorParamTypes;
final Object[] constructorParams;
if (path == null) {
constructorParamTypes = new Class[] { servletContextClass };
constructorParams = new Object[] { servletContext };
} else {
constructorParamTypes = new Class[] { servletContextClass, String.class };
constructorParams = new Object[] { servletContext, path };
}
setTemplateLoader((TemplateLoader) webappTemplateLoaderClass.getConstructor(constructorParamTypes).newInstance(constructorParams));
} catch (Exception e) {
throw new BugException(e);
}
}
use of freemarker.core.BugException in project freemarker by apache.
the class TaglibFactory method addTldLocationsFromMetaInfTlds.
private void addTldLocationsFromMetaInfTlds() throws IOException, SAXException {
if (metaInfTldSources == null || metaInfTldSources.isEmpty()) {
return;
}
Set /*<URLWithExternalForm>*/
cpMetaInfDirUrlsWithEF = null;
// Skip past the last "clear":
int srcIdxStart = 0;
for (int i = metaInfTldSources.size() - 1; i >= 0; i--) {
if (metaInfTldSources.get(i) instanceof ClearMetaInfTldSource) {
srcIdxStart = i + 1;
break;
}
}
for (int srcIdx = srcIdxStart; srcIdx < metaInfTldSources.size(); srcIdx++) {
MetaInfTldSource miTldSource = (MetaInfTldSource) metaInfTldSources.get(srcIdx);
if (miTldSource == WebInfPerLibJarMetaInfTldSource.INSTANCE) {
addTldLocationsFromWebInfPerLibJarMetaInfTlds();
} else if (miTldSource instanceof ClasspathMetaInfTldSource) {
ClasspathMetaInfTldSource cpMiTldLocation = (ClasspathMetaInfTldSource) miTldSource;
if (LOG.isDebugEnabled()) {
LOG.debug("Looking for TLD-s in " + "classpathRoots[" + cpMiTldLocation.getRootContainerPattern() + "]" + META_INF_ABS_PATH + "**/*.tld");
}
if (cpMetaInfDirUrlsWithEF == null) {
cpMetaInfDirUrlsWithEF = collectMetaInfUrlsFromClassLoaders();
}
for (Iterator iterator = cpMetaInfDirUrlsWithEF.iterator(); iterator.hasNext(); ) {
URLWithExternalForm urlWithEF = (URLWithExternalForm) iterator.next();
final URL url = urlWithEF.getUrl();
final boolean isJarUrl = isJarUrl(url);
final String urlEF = urlWithEF.externalForm;
final String rootContainerUrl;
if (isJarUrl) {
int sep = urlEF.indexOf(JAR_URL_ENTRY_PATH_START);
rootContainerUrl = sep != -1 ? urlEF.substring(0, sep) : urlEF;
} else {
rootContainerUrl = urlEF.endsWith(META_INF_ABS_PATH) ? urlEF.substring(0, urlEF.length() - META_INF_REL_PATH.length()) : urlEF;
}
if (cpMiTldLocation.getRootContainerPattern().matcher(rootContainerUrl).matches()) {
final File urlAsFile = urlToFileOrNull(url);
if (urlAsFile != null) {
addTldLocationsFromFileDirectory(urlAsFile);
} else if (isJarUrl) {
addTldLocationsFromJarDirectoryEntryURL(url);
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("Can't list entries under this URL; TLD-s won't be discovered here: " + urlWithEF.getExternalForm());
}
}
}
}
} else {
throw new BugException();
}
}
}
Aggregations