package org.faceletslite.imp; import java.io.IOException; import java.io.StringReader; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Logger; import javax.el.ArrayELResolver; import javax.el.BeanELResolver; import javax.el.CompositeELResolver; import javax.el.ELResolver; import javax.el.ExpressionFactory; import javax.el.FunctionMapper; import javax.el.ListELResolver; import javax.el.MapELResolver; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerFactory; import org.faceletslite.Configuration; import org.faceletslite.CustomTag; import org.faceletslite.Facelet; import org.faceletslite.FaceletsCompiler; import org.faceletslite.Namespace; import org.faceletslite.ResourceReader; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; import org.xml.sax.SAXException; public class DefaultConfiguration implements Configuration { private static final Logger log = Logger.getLogger(FaceletsCompiler.class.getName()); static String DEFAULT_EXPRESSION_FACTORY_CLASS = "de.odysseus.el.ExpressionFactoryImpl"; private final List<Namespace> namespaces = new ArrayList<Namespace>(); private final Map<String,List<Class<?>>> classesByPrefix = new HashMap<String, List<Class<?>>>(); public DocumentBuilderFactory getDocumentBuilderFactory() { try { DocumentBuilderFactory factory = null; try { factory = (DocumentBuilderFactory)Class.forName("org.apache.xerces.jaxp.DocumentBuilderFactoryImpl").newInstance(); } catch (Exception exc) { } if (factory==null) { factory = DocumentBuilderFactory.newInstance(); } factory.setNamespaceAware(true); factory.setExpandEntityReferences(false); factory.setValidating(false); factory.setIgnoringElementContentWhitespace(true); factory.setXIncludeAware(false); //factory.setFeature("http://apache.org/xml/features/validation/unparsed-entity-checking", false); factory.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false); factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); log.info("using "+factory.getClass().getName()); return factory; } catch (ParserConfigurationException exc) { throw new RuntimeException("XML setup failure", exc); } } @Override public DocumentBuilder createDocumentBuilder() { try { DocumentBuilder builder = getDocumentBuilderFactory().newDocumentBuilder(); builder.setEntityResolver( new EntityResolver() { @Override public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { return new InputSource(new StringReader("")); } } ); return builder; } catch (ParserConfigurationException exc) { throw new RuntimeException("XML setup failure", exc); } } public TransformerFactory getTransformerFactory() { TransformerFactory result = null; try { result = (TransformerFactory)Class.forName("org.apache.xalan.processor.TransformerFactoryImpl").newInstance(); } catch (Exception exc) { } if (result==null) { result = TransformerFactory.newInstance(); } log.info("using "+result.getClass().getName()); return result; } @Override public Transformer createDocumentTransformer() { try { Transformer result = getTransformerFactory().newTransformer(); result.setOutputProperty(OutputKeys.INDENT, "yes"); result.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); return result; } catch (TransformerConfigurationException exc) { throw new RuntimeException("XML setup failure", exc); } } @Override public ExpressionFactory getExpressionFactory() { try { java.util.Properties properties = new java.util.Properties(); properties.put("javax.el.cacheSize", "10000"); // ten times the default Class<?>[] constructorParams = new Class<?>[1]; constructorParams[0] = Properties.class; Constructor<?> constructor = Class.forName(DEFAULT_EXPRESSION_FACTORY_CLASS).getConstructor(constructorParams); return (ExpressionFactory) constructor.newInstance(properties); } catch (ClassNotFoundException exc) { // fall through } catch (Exception exc) { throw new RuntimeException("cannot instantiate JUEL", exc); } return ExpressionFactory.newInstance(); } @Override public ELResolver getELResolver() { CompositeELResolver result = new CompositeELResolver(); result.add(new MapELResolver()); result.add(new ArrayELResolver()); result.add(new ListELResolver()); result.add(new BeanELResolver()); return result; } @Override public ResourceReader getResourceReader() { return new FileResourceReader("", ".html"); } @Override public List<Namespace> getCustomNamespaces() { return namespaces; } public void addCustomNamespace(String uri, ResourceReader resourceReader) { addCustomNamespace(uri, resourceReader, Collections.<String, CustomTag>emptyMap()); } public void addCustomNamespace( final String uri, final ResourceReader resourceReader, final Map<String, CustomTag> customTags ) { namespaces.add( new Namespace() { @Override public String getUri() { return uri; } @Override public ResourceReader getResourceReader() { return resourceReader; } @Override public CustomTag getCustomTag(String tagName) { return customTags.get(tagName); } } ); } @Override public FunctionMapper getFunctionMapper() { return new FunctionMapperImp(classesByPrefix); } public void addFunctions(String prefix, Class<?> clazz) { List<Class<?>> classes = classesByPrefix.get(prefix); if (classes==null) { classes = new ArrayList<Class<?>>(); classesByPrefix.put(prefix, classes); } classes.add(clazz); } @Override public Map<String, Facelet> getCache() { return new ConcurrentHashMap<String, Facelet>(); } }