blob: 53d638b2c1d11274b6a1818fbf8a854f6c2837fc [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.myfaces.view.facelets.compiler;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import javax.el.ELException;
import javax.el.MethodExpression;
import javax.el.ValueExpression;
import javax.faces.FacesException;
import javax.faces.view.Location;
import javax.faces.view.facelets.FaceletException;
import javax.faces.view.facelets.FaceletHandler;
import javax.faces.view.facelets.Tag;
import javax.faces.view.facelets.TagAttribute;
import javax.faces.view.facelets.TagAttributes;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.apache.myfaces.config.element.FaceletsProcessing;
import org.apache.myfaces.util.lang.ClassUtils;
import org.apache.myfaces.view.facelets.tag.TagAttributeImpl;
import org.apache.myfaces.view.facelets.tag.TagAttributesImpl;
import org.apache.myfaces.view.facelets.tag.composite.CompositeLibrary;
import org.apache.myfaces.view.facelets.tag.composite.ImplementationHandler;
import org.apache.myfaces.view.facelets.tag.composite.InterfaceHandler;
import org.apache.myfaces.view.facelets.tag.jsf.core.CoreLibrary;
import org.apache.myfaces.view.facelets.tag.ui.UILibrary;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.DefaultHandler;
/**
* Compiler implementation that uses SAX
*
* @see org.apache.myfaces.view.facelets.compiler.Compiler
*
* @author Jacob Hookom
* @version $Id$
*/
public final class SAXCompiler extends Compiler
{
private final static Pattern XML_DECLARATION = Pattern
.compile("^<\\?xml.+?version=['\"](.+?)['\"](.+?encoding=['\"]((.+?))['\"])?.*?\\?>");
/**
* see https://issues.apache.org/jira/browse/MYFACES-4281
*/
private final static List<String> SKIPPED_NAMESPACES = Arrays.asList("http://www.w3.org/1998/Math/MathML",
"http://www.w3.org/2000/svg","http://www.w3.org/1999/xlink");
private static class CompilationHandler extends DefaultHandler implements LexicalHandler
{
private final String alias;
private boolean inDocument = false;
private Locator locator;
private final CompilationManager unit;
private boolean consumingCDATA = false;
private boolean swallowCDATAContent = false;
public CompilationHandler(CompilationManager unit, String alias)
{
this.unit = unit;
this.alias = alias;
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException
{
if (this.inDocument && (!consumingCDATA || (consumingCDATA && !swallowCDATAContent)))
{
this.unit.writeText(new String(ch, start, length));
}
}
@Override
public void comment(char[] ch, int start, int length) throws SAXException
{
if (this.inDocument && !unit.getFaceletsProcessingInstructions().isConsumeXMLComments())
{
this.unit.writeComment(new String(ch, start, length));
}
}
protected TagAttributes createAttributes(Attributes attrs)
{
int len = attrs.getLength();
TagAttribute[] ta = new TagAttribute[len];
for (int i = 0; i < len; i++)
{
ta[i] = new TagAttributeImpl(this.createLocation(), attrs.getURI(i), attrs.getLocalName(i),
attrs.getQName(i), attrs.getValue(i));
}
return new TagAttributesImpl(ta);
}
protected Location createLocation()
{
return new Location(this.alias, this.locator.getLineNumber(), this.locator.getColumnNumber());
}
@Override
public void endCDATA() throws SAXException
{
if (this.inDocument)
{
if (!this.unit.getFaceletsProcessingInstructions().isConsumeCDataSections())
{
this.unit.writeInstruction("]]>");
}
else
{
this.consumingCDATA = false;
this.swallowCDATAContent = false;
}
}
}
@Override
public void endDTD() throws SAXException
{
this.inDocument = true;
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException
{
this.unit.popTag();
}
@Override
public void endEntity(String name) throws SAXException
{
}
@Override
public void endPrefixMapping(String prefix) throws SAXException
{
this.unit.popNamespace(prefix);
}
@Override
public void fatalError(SAXParseException e) throws SAXException
{
if (this.locator != null)
{
throw new SAXException("Error Traced[line: " + this.locator.getLineNumber() + "] " + e.getMessage());
}
else
{
throw e;
}
}
@Override
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException
{
if (this.inDocument)
{
this.unit.writeWhitespace(new String(ch, start, length));
}
}
@Override
public InputSource resolveEntity(String publicId, String systemId) throws SAXException
{
String dtd = "org/apache/myfaces/resource/default.dtd";
/*
* if ("-//W3C//DTD XHTML 1.0 Transitional//EN".equals(publicId)) { dtd = "xhtml1-transitional.dtd"; } else
* if (systemId != null && systemId.startsWith("file:/")) { return new InputSource(systemId); }
*/
URL url = ClassUtils.getResource(dtd);
return new InputSource(url.toString());
}
@Override
public void setDocumentLocator(Locator locator)
{
this.locator = locator;
}
@Override
public void startCDATA() throws SAXException
{
if (this.inDocument)
{
if (!this.unit.getFaceletsProcessingInstructions().isConsumeCDataSections())
{
this.unit.writeInstruction("<![CDATA[");
}
else
{
this.consumingCDATA = true;
this.swallowCDATAContent = this.unit.getFaceletsProcessingInstructions().isSwallowCDataContent();
}
}
}
@Override
public void startDocument() throws SAXException
{
this.inDocument = true;
}
@Override
public void startDTD(String name, String publicId, String systemId) throws SAXException
{
if (this.inDocument && !unit.getFaceletsProcessingInstructions().isConsumeXmlDocType())
{
this.unit.writeDoctype(name, publicId, systemId);
/*
StringBuffer sb = new StringBuffer(64);
sb.append("<!DOCTYPE ").append(name);
if (publicId != null)
{
sb.append(" PUBLIC \"").append(publicId).append("\"");
if (systemId != null)
{
sb.append(" \"").append(systemId).append("\"");
}
}
else if (systemId != null)
{
sb.append(" SYSTEM \"").append(systemId).append("\"");
}
sb.append(" >\n");
this.unit.writeInstruction(sb.toString());
*/
}
this.inDocument = false;
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
{
this.unit.pushTag(new Tag(this.createLocation(), uri, localName, qName, this.createAttributes(attributes)));
}
@Override
public void startEntity(String name) throws SAXException
{
}
@Override
public void startPrefixMapping(String prefix, String uri) throws SAXException
{
if (!SKIPPED_NAMESPACES.contains(uri))
{
this.unit.pushNamespace(prefix, uri);
}
}
@Override
public void processingInstruction(String target, String data) throws SAXException
{
if (this.inDocument && !this.unit.getFaceletsProcessingInstructions().isConsumeProcessingInstructions())
{
StringBuilder sb = new StringBuilder(64);
sb.append("<?").append(target).append(' ').append(data).append("?>\n");
this.unit.writeInstruction(sb.toString());
}
}
}
/**
* Like CompilationHandler but does not take into account everything outside f:metadata tag
*
* @since 2.0
*/
private static class ViewMetadataHandler extends DefaultHandler implements LexicalHandler
{
private final String alias;
private boolean inDocument = false;
private Locator locator;
private final CompilationManager unit;
private boolean inMetadata = false;
private int uiRemoveCount = 0;
private boolean consumingCDATA = false;
private boolean swallowCDATAContent = false;
public ViewMetadataHandler(CompilationManager unit, String alias)
{
this.unit = unit;
this.alias = alias;
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException
{
if (this.inDocument && inMetadata && (!consumingCDATA || (consumingCDATA && !swallowCDATAContent)))
{
this.unit.writeText(new String(ch, start, length));
}
}
@Override
public void comment(char[] ch, int start, int length) throws SAXException
{
if (this.inDocument && inMetadata && !unit.getFaceletsProcessingInstructions().isConsumeXMLComments())
{
this.unit.writeComment(new String(ch, start, length));
}
}
protected TagAttributes createAttributes(Attributes attrs)
{
int len = attrs.getLength();
TagAttribute[] ta = new TagAttribute[len];
for (int i = 0; i < len; i++)
{
ta[i] = new TagAttributeImpl(this.createLocation(), attrs.getURI(i), attrs.getLocalName(i), attrs
.getQName(i), attrs.getValue(i));
}
return new TagAttributesImpl(ta);
}
protected Location createLocation()
{
return new Location(this.alias, this.locator.getLineNumber(), this.locator.getColumnNumber());
}
@Override
public void endCDATA() throws SAXException
{
if (this.inDocument && inMetadata)
{
if (!this.unit.getFaceletsProcessingInstructions().isConsumeCDataSections())
{
this.unit.writeInstruction("]]>");
}
else
{
this.consumingCDATA = false;
this.swallowCDATAContent = false;
}
}
}
@Override
public void endDTD() throws SAXException
{
this.inDocument = true;
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException
{
if (inMetadata)
{
this.unit.popTag();
}
if ((CoreLibrary.NAMESPACE.equals(uri) || CoreLibrary.ALIAS_NAMESPACE.equals(uri)))
{
if ("metadata".equals(localName))
{
this.inMetadata=false;
}
else if (!inMetadata && "view".equals(localName))
{
this.unit.popTag();
}
}
else if (UILibrary.NAMESPACE.equals(uri) || UILibrary.ALIAS_NAMESPACE.equals(uri))
{
if (!inMetadata && "remove".equals(localName))
{
this.uiRemoveCount--;
}
}
}
@Override
public void endEntity(String name) throws SAXException
{
}
@Override
public void endPrefixMapping(String prefix) throws SAXException
{
this.unit.popNamespace(prefix);
}
@Override
public void fatalError(SAXParseException e) throws SAXException
{
if (this.locator != null)
{
throw new SAXException("Error Traced[line: " + this.locator.getLineNumber() + "] " + e.getMessage());
}
else
{
throw e;
}
}
@Override
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException
{
if (this.inDocument && inMetadata)
{
this.unit.writeWhitespace(new String(ch, start, length));
}
}
@Override
public InputSource resolveEntity(String publicId, String systemId) throws SAXException
{
String dtd = "org/apache/myfaces/resource/default.dtd";
/*
* if ("-//W3C//DTD XHTML 1.0 Transitional//EN".equals(publicId)) { dtd = "xhtml1-transitional.dtd"; } else
* if (systemId != null && systemId.startsWith("file:/")) { return new InputSource(systemId); }
*/
URL url = ClassUtils.getResource(dtd);
return new InputSource(url.toString());
}
@Override
public void setDocumentLocator(Locator locator)
{
this.locator = locator;
}
@Override
public void startCDATA() throws SAXException
{
if (this.inDocument && inMetadata)
{
if (!this.unit.getFaceletsProcessingInstructions().isConsumeCDataSections())
{
this.unit.writeInstruction("<![CDATA[");
}
else
{
this.consumingCDATA = true;
this.swallowCDATAContent = this.unit.getFaceletsProcessingInstructions().isSwallowCDataContent();
}
}
}
@Override
public void startDocument() throws SAXException
{
this.inDocument = true;
}
@Override
public void startDTD(String name, String publicId, String systemId) throws SAXException
{
// metadata does not require output doctype
this.inDocument = false;
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
{
if ( (CoreLibrary.NAMESPACE.equals(uri) ||
CoreLibrary.ALIAS_NAMESPACE.equals(uri)) && this.uiRemoveCount <= 0)
{
if ("metadata".equals(localName))
{
this.inMetadata=true;
}
else if (!inMetadata && "view".equals(localName))
{
this.unit.pushTag(new Tag(createLocation(), uri, localName, qName, createAttributes(attributes)));
}
}
if (inMetadata)
{
this.unit.pushTag(new Tag(createLocation(), uri, localName, qName, createAttributes(attributes)));
}
else if (UILibrary.NAMESPACE.equals(uri) ||
UILibrary.ALIAS_NAMESPACE.equals(uri))
{
if ("remove".equals(localName))
{
this.uiRemoveCount++;
}
}
}
@Override
public void startEntity(String name) throws SAXException
{
}
@Override
public void startPrefixMapping(String prefix, String uri) throws SAXException
{
this.unit.pushNamespace(prefix, uri);
}
@Override
public void processingInstruction(String target, String data) throws SAXException
{
if (inDocument && inMetadata && !unit.getFaceletsProcessingInstructions().isConsumeProcessingInstructions())
{
StringBuilder sb = new StringBuilder(64);
sb.append("<?").append(target).append(' ').append(data).append("?>\n");
unit.writeInstruction(sb.toString());
}
}
}
/**
* Like CompilationHandler but does not take into account everything outside cc:interface or cc:implementation tag.
*
* Note inside cc:implementation it only takes into account cc:insertChildren, cc:insertFacet and cc:renderFacet,
* all other tags, comments or text are just skipped.
*
* @since 2.0.1
*/
private static class CompositeComponentMetadataHandler extends DefaultHandler implements LexicalHandler
{
private final String alias;
private boolean inDocument = false;
private Locator locator;
private final CompilationManager unit;
private boolean inCompositeInterface = false;
private boolean inCompositeImplementation = false;
private boolean consumingCDATA = false;
private boolean swallowCDATAContent = false;
public CompositeComponentMetadataHandler(CompilationManager unit, String alias)
{
this.unit = unit;
this.alias = alias;
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException
{
if (this.inDocument && inCompositeInterface &&
(!consumingCDATA || (consumingCDATA && !swallowCDATAContent)))
{
this.unit.writeText(new String(ch, start, length));
}
}
@Override
public void comment(char[] ch, int start, int length) throws SAXException
{
if (inDocument && inCompositeInterface &&
!unit.getFaceletsProcessingInstructions().isConsumeXMLComments())
{
this.unit.writeComment(new String(ch, start, length));
}
}
protected TagAttributes createAttributes(Attributes attrs)
{
int len = attrs.getLength();
TagAttribute[] ta = new TagAttribute[len];
for (int i = 0; i < len; i++)
{
ta[i] = new TagAttributeImpl(this.createLocation(), attrs.getURI(i), attrs.getLocalName(i), attrs
.getQName(i), attrs.getValue(i));
}
return new TagAttributesImpl(ta);
}
protected Location createLocation()
{
return new Location(this.alias, this.locator.getLineNumber(), this.locator.getColumnNumber());
}
@Override
public void endCDATA() throws SAXException
{
if (this.inDocument && inCompositeInterface)
{
if (!this.unit.getFaceletsProcessingInstructions().isConsumeCDataSections())
{
this.unit.writeInstruction("]]>");
}
else
{
this.consumingCDATA = false;
this.swallowCDATAContent = false;
}
}
}
@Override
public void endDTD() throws SAXException
{
this.inDocument = true;
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException
{
if (inCompositeInterface)
{
this.unit.popTag();
}
else if (inCompositeImplementation &&
(CompositeLibrary.NAMESPACE.equals(uri) || CompositeLibrary.ALIAS_NAMESPACE.equals(uri)) )
{
if ("insertFacet".equals(localName) ||
"renderFacet".equals(localName) ||
"insertChildren".equals(localName) ||
ImplementationHandler.NAME.equals(localName))
{
this.unit.popTag();
}
}
if (CompositeLibrary.NAMESPACE.equals(uri) || CompositeLibrary.ALIAS_NAMESPACE.equals(uri))
{
if (InterfaceHandler.NAME.equals(localName))
{
this.inCompositeInterface=false;
}
else if (ImplementationHandler.NAME.equals(localName))
{
this.inCompositeImplementation=false;
}
}
}
@Override
public void endEntity(String name) throws SAXException
{
}
@Override
public void endPrefixMapping(String prefix) throws SAXException
{
this.unit.popNamespace(prefix);
}
@Override
public void fatalError(SAXParseException e) throws SAXException
{
if (this.locator != null)
{
throw new SAXException("Error Traced[line: " + this.locator.getLineNumber() + "] " + e.getMessage());
}
throw e;
}
@Override
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException
{
if (this.inDocument && inCompositeInterface)
{
this.unit.writeWhitespace(new String(ch, start, length));
}
}
@Override
public InputSource resolveEntity(String publicId, String systemId) throws SAXException
{
String dtd = "org/apache/myfaces/resource/default.dtd";
/*
* if ("-//W3C//DTD XHTML 1.0 Transitional//EN".equals(publicId)) { dtd = "xhtml1-transitional.dtd"; } else
* if (systemId != null && systemId.startsWith("file:/")) { return new InputSource(systemId); }
*/
URL url = ClassUtils.getResource(dtd);
return new InputSource(url.toString());
}
@Override
public void setDocumentLocator(Locator locator)
{
this.locator = locator;
}
@Override
public void startCDATA() throws SAXException
{
if (this.inDocument && inCompositeInterface)
{
if (!this.unit.getFaceletsProcessingInstructions().isConsumeCDataSections())
{
this.unit.writeInstruction("<![CDATA[");
}
else
{
this.consumingCDATA = true;
this.swallowCDATAContent = this.unit.getFaceletsProcessingInstructions().isSwallowCDataContent();
}
}
}
@Override
public void startDocument() throws SAXException
{
this.inDocument = true;
}
@Override
public void startDTD(String name, String publicId, String systemId) throws SAXException
{
// metadata does not require output doctype
this.inDocument = false;
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
{
if (CompositeLibrary.NAMESPACE.equals(uri) || CompositeLibrary.ALIAS_NAMESPACE.equals(uri))
{
if (InterfaceHandler.NAME.equals(localName))
{
this.inCompositeInterface=true;
}
else if (ImplementationHandler.NAME.equals(localName))
{
this.inCompositeImplementation=true;
}
}
if (inCompositeInterface)
{
this.unit.pushTag(new Tag(createLocation(), uri, localName, qName, createAttributes(attributes)));
}
else if (inCompositeImplementation &&
(CompositeLibrary.NAMESPACE.equals(uri) || CompositeLibrary.ALIAS_NAMESPACE.equals(uri)))
{
if ("insertFacet".equals(localName) ||
"renderFacet".equals(localName) ||
"insertChildren".equals(localName) ||
ImplementationHandler.NAME.equals(localName) )
{
this.unit.pushTag(new Tag(createLocation(), uri, localName, qName, createAttributes(attributes)));
}
}
}
@Override
public void startEntity(String name) throws SAXException
{
}
@Override
public void startPrefixMapping(String prefix, String uri) throws SAXException
{
this.unit.pushNamespace(prefix, uri);
}
@Override
public void processingInstruction(String target, String data) throws SAXException
{
if (inDocument
&& inCompositeInterface
&& !unit.getFaceletsProcessingInstructions().isConsumeProcessingInstructions())
{
StringBuilder sb = new StringBuilder(64);
sb.append("<?").append(target).append(' ').append(data).append("?>\n");
this.unit.writeInstruction(sb.toString());
}
}
}
public SAXCompiler()
{
super();
}
@Override
public FaceletHandler doCompile(URL src, String alias)
throws IOException, FaceletException, ELException, FacesException
{
CompilationManager mngr = null;
InputStream is = null;
String encoding = null;
try
{
is = new BufferedInputStream(src.openStream(), 1024);
mngr = new CompilationManager(alias, this, getFaceletsProcessingInstructions(src, alias));
encoding = writeXmlDecl(is, mngr);
CompilationHandler handler = new CompilationHandler(mngr, alias);
SAXParser parser = this.createSAXParser(handler);
parser.parse(is, handler);
}
catch (SAXException e)
{
throw new FaceletException("Error Parsing " + alias + ": " + e.getMessage(), e.getCause());
}
catch (ParserConfigurationException e)
{
throw new FaceletException("Error Configuring Parser " + alias + ": " + e.getMessage(), e.getCause());
}
finally
{
if (is != null)
{
is.close();
}
}
return new EncodingHandler(mngr.createFaceletHandler(), encoding);
}
/**
* @since 2.0
*/
@Override
protected FaceletHandler doCompileViewMetadata(URL src, String alias)
throws IOException, FaceletException, ELException, FacesException
{
CompilationManager mngr = null;
InputStream is = null;
String encoding = null;
try
{
is = new BufferedInputStream(src.openStream(), 1024);
mngr = new CompilationManager(alias, this, getFaceletsProcessingInstructions(src, alias));
encoding = getXmlDecl(is, mngr);
final ViewMetadataHandler handler = new ViewMetadataHandler(mngr, alias);
final SAXParser parser = this.createSAXParser(handler);
if (System.getSecurityManager() != null)
{
try
{
final InputStream finalInputStream = is;
AccessController.doPrivileged((PrivilegedExceptionAction) () -> {
parser.parse(finalInputStream, handler);
return null;
});
}
catch (PrivilegedActionException pae)
{
Exception e = pae.getException();
if(e instanceof SAXException)
{
throw new FaceletException("Error Parsing " + alias + ": " + e.getMessage(), e.getCause());
}
else if(e instanceof IOException)
{
throw (IOException)e;
}
}
}
else
{
parser.parse(is, handler);
}
}
catch (SAXException e)
{
throw new FaceletException("Error Parsing " + alias + ": " + e.getMessage(), e.getCause());
}
catch (ParserConfigurationException e)
{
throw new FaceletException("Error Configuring Parser " + alias + ": " + e.getMessage(), e.getCause());
}
finally
{
if (is != null)
{
is.close();
}
}
return new EncodingHandler(mngr.createFaceletHandler(), encoding);
}
/**
* @since 2.0.1
*/
@Override
protected FaceletHandler doCompileCompositeComponentMetadata(URL src, String alias)
throws IOException, FaceletException, ELException, FacesException
{
CompilationManager mngr = null;
InputStream is = null;
String encoding = null;
try
{
is = new BufferedInputStream(src.openStream(), 1024);
mngr = new CompilationManager(alias, this, getFaceletsProcessingInstructions(src, alias));
encoding = getXmlDecl(is, mngr);
CompositeComponentMetadataHandler handler = new CompositeComponentMetadataHandler(mngr, alias);
SAXParser parser = this.createSAXParser(handler);
parser.parse(is, handler);
}
catch (SAXException e)
{
throw new FaceletException("Error Parsing " + alias + ": " + e.getMessage(), e.getCause());
}
catch (ParserConfigurationException e)
{
throw new FaceletException("Error Configuring Parser " + alias + ": " + e.getMessage(), e.getCause());
}
finally
{
if (is != null)
{
is.close();
}
}
return new EncodingHandler(mngr.createFaceletHandler(), encoding);
}
@Override
protected FaceletHandler doCompileComponent(
String taglibURI, String tagName, Map<String, Object> attributes)
{
String alias = tagName;
CompilationManager mngr = new CompilationManager(alias, this, getDefaultFaceletsProcessingInstructions());
String prefix = "oamf"; // The prefix is only a logical name.
mngr.pushNamespace(prefix, taglibURI);
boolean tagContainParams = (
("include".equals(tagName) || "decorate".equals(tagName) || "composition".equals(tagName)) &&
(UILibrary.NAMESPACE.equals(taglibURI) || UILibrary.ALIAS_NAMESPACE.equals(taglibURI)) );
Location location = new Location(alias, 0, 0);
int len = attributes.size();
if (tagContainParams && attributes.containsKey("params"))
{
len = len-1;
}
TagAttribute[] ta = new TagAttribute[len];
int i = 0;
Map<String, Object> paramsMap = null;
for (Map.Entry<String, Object> entry : attributes.entrySet())
{
String stringValue = null;
if (tagContainParams && "params".equals(entry.getKey()))
{
paramsMap = (Map<String, Object>) entry.getValue();
}
else
{
if (entry.getValue() instanceof ValueExpression)
{
stringValue = ((ValueExpression) entry.getValue()).getExpressionString();
}
else if (entry.getValue() instanceof MethodExpression)
{
stringValue = ((MethodExpression) entry.getValue()).getExpressionString();
}
else if (entry.getValue() != null)
{
stringValue = entry.getValue().toString();
}
ta[i] = new TagAttributeImpl(location, "", entry.getKey(), entry.getKey(), stringValue);
i++;
}
}
mngr.pushTag(new Tag(location, taglibURI, tagName, "oamf:"+tagName, new TagAttributesImpl(ta)));
if (tagContainParams && paramsMap != null)
{
for (Map.Entry<String, Object> entry : paramsMap.entrySet())
{
TagAttribute[] tap = new TagAttribute[2];
String stringValue = null;
if (entry.getValue() instanceof ValueExpression)
{
stringValue = ((ValueExpression)entry.getValue()).getExpressionString();
}
else if (entry.getValue() instanceof MethodExpression)
{
stringValue = ((MethodExpression)entry.getValue()).getExpressionString();
}
else if (entry.getValue() != null)
{
stringValue = entry.getValue().toString();
}
tap[0] = new TagAttributeImpl(location, "", "name", "name", entry.getKey());
tap[1] = new TagAttributeImpl(location, "", "value", "value", stringValue);
mngr.pushTag(new Tag(location, UILibrary.NAMESPACE, "param", "oamf:param", new TagAttributesImpl(tap)));
mngr.popTag();
}
}
mngr.popTag();
mngr.popNamespace(prefix);
FaceletHandler handler = new DynamicComponentFacelet((NamespaceHandler) mngr.createFaceletHandler());
return handler;
}
protected FaceletsProcessingInstructions getDefaultFaceletsProcessingInstructions()
{
return FaceletsProcessingInstructions.getProcessingInstructions(FaceletsProcessing.PROCESS_AS_XHTML, false);
}
protected FaceletsProcessingInstructions getFaceletsProcessingInstructions(URL src, String alias)
{
String processAs = null;
boolean compressSpaces = false;
for (FaceletsProcessing entry : getFaceletsProcessingConfigurations())
{
if (src.getPath().endsWith(entry.getFileExtension()))
{
processAs = entry.getProcessAs();
compressSpaces = Boolean.valueOf(entry.getOamCompressSpaces());
break;
}
}
return FaceletsProcessingInstructions.getProcessingInstructions(processAs, compressSpaces);
}
protected static String writeXmlDecl(InputStream is, CompilationManager mngr) throws IOException
{
is.mark(128);
String encoding = null;
try
{
byte[] b = new byte[128];
if (is.read(b) > 0)
{
String r = new String(b);
Matcher m = XML_DECLARATION.matcher(r);
if (m.find())
{
if (!mngr.getFaceletsProcessingInstructions().isConsumeXmlDeclaration())
{
mngr.writeInstruction(m.group(0) + '\n');
}
if (m.group(3) != null)
{
encoding = m.group(3);
}
}
}
}
finally
{
is.reset();
}
return encoding;
}
protected static String getXmlDecl(InputStream is, CompilationManager mngr) throws IOException
{
is.mark(128);
String encoding = null;
try
{
byte[] b = new byte[128];
if (is.read(b) > 0)
{
String r = new String(b);
Matcher m = XML_DECLARATION.matcher(r);
if (m.find() && m.group(3) != null)
{
encoding = m.group(3);
}
}
}
finally
{
is.reset();
}
return encoding;
}
private SAXParser createSAXParser(DefaultHandler handler) throws SAXException,
ParserConfigurationException
{
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
factory.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
factory.setValidating(this.isValidating());
factory.setFeature("http://xml.org/sax/features/validation", this.isValidating());
SAXParser parser = factory.newSAXParser();
XMLReader reader = parser.getXMLReader();
reader.setProperty("http://xml.org/sax/properties/lexical-handler", handler);
reader.setErrorHandler(handler);
reader.setEntityResolver(handler);
return parser;
}
}