Author: nbelaevski
Date: 2010-05-27 21:39:29 -0400 (Thu, 27 May 2010)
New Revision: 17336
Added:
root/build/resources/trunk/faces-shade-transformers/
root/build/resources/trunk/faces-shade-transformers/pom.xml
root/build/resources/trunk/faces-shade-transformers/src/
root/build/resources/trunk/faces-shade-transformers/src/main/
root/build/resources/trunk/faces-shade-transformers/src/main/java/
root/build/resources/trunk/faces-shade-transformers/src/main/java/org/
root/build/resources/trunk/faces-shade-transformers/src/main/java/org/richfaces/
root/build/resources/trunk/faces-shade-transformers/src/main/java/org/richfaces/build/
root/build/resources/trunk/faces-shade-transformers/src/main/java/org/richfaces/build/shade/
root/build/resources/trunk/faces-shade-transformers/src/main/java/org/richfaces/build/shade/resource/
root/build/resources/trunk/faces-shade-transformers/src/main/java/org/richfaces/build/shade/resource/BaseFacesResourceTransformer.java
root/build/resources/trunk/faces-shade-transformers/src/main/java/org/richfaces/build/shade/resource/ElementsComparator.java
root/build/resources/trunk/faces-shade-transformers/src/main/java/org/richfaces/build/shade/resource/FacesConfigXmlResourceTransformer.java
root/build/resources/trunk/faces-shade-transformers/src/main/java/org/richfaces/build/shade/resource/Taglib.java
root/build/resources/trunk/faces-shade-transformers/src/main/java/org/richfaces/build/shade/resource/TaglibXmlResourceTransformer.java
Modified:
root/pom.xml
Log:
faces-shade-transformers module initial check-in
Added: root/build/resources/trunk/faces-shade-transformers/pom.xml
===================================================================
--- root/build/resources/trunk/faces-shade-transformers/pom.xml
(rev 0)
+++ root/build/resources/trunk/faces-shade-transformers/pom.xml 2010-05-28 01:39:29 UTC
(rev 17336)
@@ -0,0 +1,46 @@
+<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.richfaces</groupId>
+ <artifactId>richfaces-parent</artifactId>
+ <version>6</version>
+ </parent>
+
+ <groupId>org.richfaces.build.resources</groupId>
+ <artifactId>faces-shade-transformers</artifactId>
+ <version>4.0.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+ <name>JSF configuration files ransformers for maven-shade-plugin</name>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <version>1.3.3</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jdom</groupId>
+ <artifactId>jdom</artifactId>
+ <version>1.1</version>
+ </dependency>
+ <dependency>
+ <groupId>jaxen</groupId>
+ <artifactId>jaxen</artifactId>
+ <version>1.1.1</version>
+ </dependency>
+ </dependencies>
+</project>
Added:
root/build/resources/trunk/faces-shade-transformers/src/main/java/org/richfaces/build/shade/resource/BaseFacesResourceTransformer.java
===================================================================
---
root/build/resources/trunk/faces-shade-transformers/src/main/java/org/richfaces/build/shade/resource/BaseFacesResourceTransformer.java
(rev 0)
+++
root/build/resources/trunk/faces-shade-transformers/src/main/java/org/richfaces/build/shade/resource/BaseFacesResourceTransformer.java 2010-05-28
01:39:29 UTC (rev 17336)
@@ -0,0 +1,179 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.richfaces.build.shade.resource;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
+
+import org.apache.maven.plugins.shade.resource.ResourceTransformer;
+import org.jdom.Attribute;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jdom.Namespace;
+import org.jdom.input.SAXBuilder;
+import org.jdom.output.Format;
+import org.jdom.output.XMLOutputter;
+import org.jdom.xpath.XPath;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public abstract class BaseFacesResourceTransformer implements ResourceTransformer {
+
+ protected static final String META_INF_PATH = "META-INF/";
+
+ protected static final String JAVAEE_URI =
"http://java.sun.com/xml/ns/javaee";
+
+ protected static final String JAVAEE_PREFIX = "javaee";
+
+ protected static final Namespace JAVAEE_NAMESPACE =
Namespace.getNamespace(JAVAEE_PREFIX, JAVAEE_URI);
+
+ protected static final Namespace XSI_NAMESPACE =
Namespace.getNamespace("xsi",
"http://www.w3.org/2001/XMLSchema-instance");
+
+ protected static XPath createXPath(String path) throws JDOMException {
+ XPath xPath = XPath.newInstance(path);
+ xPath.addNamespace(JAVAEE_NAMESPACE);
+ xPath.addNamespace(XSI_NAMESPACE);
+
+ return xPath;
+ }
+
+ protected void addSchemaLocation(Element element, String schemaLocation) {
+ if (schemaLocation != null && schemaLocation.length() != 0) {
+ element.setAttribute("schemaLocation", JAVAEE_URI + " " +
schemaLocation, XSI_NAMESPACE);
+ }
+ }
+
+ private void updateNamespaceRecursively(Object object) {
+ if (object instanceof Element) {
+ Element element = (Element) object;
+
+ if (JAVAEE_URI.equals(element.getNamespaceURI())) {
+ element.setNamespace(JAVAEE_NAMESPACE);
+ }
+
+ for (Object attributeObject : element.getAttributes()) {
+ Attribute attribute = (Attribute) attributeObject;
+
+ if (JAVAEE_URI.equals(attribute.getNamespaceURI())) {
+ attribute.setNamespace(JAVAEE_NAMESPACE);
+ }
+ }
+
+ for (Object child : element.getChildren()) {
+ updateNamespaceRecursively(child);
+ }
+ }
+ }
+
+ protected boolean isJavaEEOrDefaultNamespace(Element element) {
+ String namespaceURI = element.getNamespaceURI();
+ if (namespaceURI == null || namespaceURI.length() == 0) {
+ return true;
+ }
+
+ return JAVAEE_URI.equals(namespaceURI);
+ }
+
+ protected Element cloneAndImportElement(Element element) {
+ Element clonedElement = (Element) element.clone();
+ updateNamespaceRecursively(clonedElement);
+ return clonedElement;
+ }
+
+ protected List<Element> cloneAndImportElements(List<Element> elements) {
+ List<Element> result = new ArrayList<Element>(elements.size());
+ for (Element element : elements) {
+ result.add(cloneAndImportElement(element));
+ }
+
+ return result;
+ }
+
+ protected void appendToStream(String resourceName, Document document, JarOutputStream
jos) throws IOException {
+ jos.putNextEntry(new JarEntry(resourceName));
+ Format prettyFormat = Format.getPrettyFormat();
+ prettyFormat.setIndent(" ");
+ new XMLOutputter(prettyFormat).output(document, jos);
+ }
+
+ protected abstract void processDocument(String resource, Document document, List
relocators) throws JDOMException;
+
+ protected String getMetaInfResourceName(String resource) {
+ if (!resource.startsWith(META_INF_PATH)) {
+ return null;
+ }
+
+ String subPath = resource.substring(META_INF_PATH.length());
+ if (subPath.contains("/")) {
+ return null;
+ }
+
+ return subPath;
+ }
+
+ @SuppressWarnings("unchecked")
+ protected <T> List<T> checkedList(List<?> list, Class<T>
clazz) {
+ for (Object o: list) {
+ if (!clazz.isInstance(o)) {
+ throw new ClassCastException(o.toString());
+ }
+ }
+
+ return (List<T>) list;
+ }
+
+ public void processResource(String resource, InputStream is, List relocators) throws
IOException {
+ try {
+ SAXBuilder builder = new SAXBuilder(false);
+ builder.setExpandEntities(false);
+ //TODO nick - namespace aware?
+ builder.setEntityResolver(new EntityResolver() {
+
+ public InputSource resolveEntity(String publicId, String systemId) throws
SAXException, IOException {
+ return new InputSource(new StringReader(""));
+ }
+ });
+ Document document = builder.build(is);
+ processDocument(resource, document, relocators);
+ } catch (JDOMException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ } finally {
+ try {
+ is.close();
+ } catch (IOException e) {
+ // TODO: handle exception
+ }
+ }
+ }
+
+}
Added:
root/build/resources/trunk/faces-shade-transformers/src/main/java/org/richfaces/build/shade/resource/ElementsComparator.java
===================================================================
---
root/build/resources/trunk/faces-shade-transformers/src/main/java/org/richfaces/build/shade/resource/ElementsComparator.java
(rev 0)
+++
root/build/resources/trunk/faces-shade-transformers/src/main/java/org/richfaces/build/shade/resource/ElementsComparator.java 2010-05-28
01:39:29 UTC (rev 17336)
@@ -0,0 +1,92 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.richfaces.build.shade.resource;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jdom.xpath.XPath;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+class ElementsComparator implements Comparator<Element> {
+
+ private String namespaceUri;
+
+ private List<String> orderedElementNames;
+
+ private Map<String, XPath> comparisonPaths;
+
+ public ElementsComparator(String namespaceUri, List<String>
orderedElementNames, Map<String, XPath> comparisonPaths) {
+ super();
+ this.namespaceUri = namespaceUri;
+ this.orderedElementNames = orderedElementNames;
+ this.comparisonPaths = comparisonPaths;
+ }
+
+ private String maskNullString(String s) {
+ return s != null ? s : "";
+ }
+
+ public int compare(Element o1, Element o2) {
+ if (!namespaceUri.equals(o1.getNamespaceURI()) ||
!namespaceUri.equals(o2.getNamespaceURI())) {
+ return 0;
+ }
+
+ String firstName = o1.getName();
+ String secondName = o2.getName();
+
+ if (firstName.equals(secondName)) {
+ XPath comparisonPath = comparisonPaths.get(firstName);
+
+ if (comparisonPath != null) {
+ try {
+ String firstEltValue = maskNullString(comparisonPath.valueOf(o1));
+ String secondEltValue = maskNullString(comparisonPath.valueOf(o2));
+
+ return firstEltValue.compareToIgnoreCase(secondEltValue);
+ } catch (JDOMException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+
+ return 0;
+ } else {
+ int firstNameIdx = orderedElementNames.indexOf(firstName);
+ int secondNameIdx = orderedElementNames.indexOf(secondName);
+
+ if (firstNameIdx < secondNameIdx) {
+ return -1;
+ } else if (firstNameIdx == secondNameIdx) {
+ return 0;
+ } else {
+ return 1;
+ }
+ }
+ }
+
+}
Added:
root/build/resources/trunk/faces-shade-transformers/src/main/java/org/richfaces/build/shade/resource/FacesConfigXmlResourceTransformer.java
===================================================================
---
root/build/resources/trunk/faces-shade-transformers/src/main/java/org/richfaces/build/shade/resource/FacesConfigXmlResourceTransformer.java
(rev 0)
+++
root/build/resources/trunk/faces-shade-transformers/src/main/java/org/richfaces/build/shade/resource/FacesConfigXmlResourceTransformer.java 2010-05-28
01:39:29 UTC (rev 17336)
@@ -0,0 +1,283 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.richfaces.build.shade.resource;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.jar.JarOutputStream;
+
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jdom.filter.ElementFilter;
+import org.jdom.filter.Filter;
+import org.jdom.xpath.XPath;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class FacesConfigXmlResourceTransformer extends BaseFacesResourceTransformer {
+
+ private static final String BEHAVIOR_ID = "behavior-id";
+ private static final String VALIDATOR_ID = "validator-id";
+ private static final String CONVERTER_ID = "converter-id";
+ private static final String COMPONENT_TYPE = "component-type";
+ private static final String RENDER_KIT_EXTENSION = "render-kit-extension";
+ private static final String CLIENT_BEHAVIOR_RENDERER =
"client-behavior-renderer";
+ private static final String ICON = "icon";
+ private static final String DISPLAY_NAME = "display-name";
+ private static final String DESCRIPTION = "description";
+ private static final String LIFECYCLE_EXTENSION = "lifecycle-extension";
+ private static final String PHASE_LISTENER = "phase-listener";
+ private static final String FACES_CONFIG_EXTENSION =
"faces-config-extension";
+ private static final String BEHAVIOR = "behavior";
+ private static final String VALIDATOR = "validator";
+ private static final String LIFECYCLE = "lifecycle";
+ private static final String REFERENCED_BEAN = "referenced-bean";
+ private static final String NAVIGATION_RULE = "navigation-rule";
+ private static final String NAME = "name";
+ private static final String MANAGED_BEAN = "managed-bean";
+ private static final String CONVERTER = "converter";
+ private static final String COMPONENT = "component";
+ private static final String FACTORY = "factory";
+ private static final String ABSOLUTE_ORDERING = "absolute-ordering";
+ private static final String ORDERING = "ordering";
+ private static final String APPLICATION = "application";
+ private static final String RENDERER = "renderer";
+ private static final String RENDER_KIT_CLASS = "render-kit-class";
+ private static final String RENDER_KIT_ID = "render-kit-id";
+ private static final String RENDER_KIT = "render-kit";
+ private static final String FACES_CONFIG = "faces-config";
+ private static final String METADATA_COMPLETE = "metadata-complete";
+ private static final String CURRENT_VERSION = "2.0";
+ private static final String VERSION = "version";
+ private static final String FACES_CONFIG_FILE_NAME = "faces-config.xml";
+
+ private static final Set<String> AGGREGATOR_ELEMENTS_NAME_SET = new
HashSet<String>(Arrays.asList(APPLICATION,
+ FACTORY, LIFECYCLE));
+
+ private static final Set<String> UNHANDLED_ELEMENTS_NAME_SET = new
HashSet<String>(Arrays.asList(ORDERING,
+ ABSOLUTE_ORDERING, NAME));
+
+ private static final String RENDER_KIT_ID_EXPRESSION =
MessageFormat.format("./{0}:{1}|./{1}", JAVAEE_PREFIX,
+ RENDER_KIT_ID);
+
+ private static final String FACES_CONFIG_FILE_PATH = META_INF_PATH +
FACES_CONFIG_FILE_NAME;
+
+ private enum ThreeState {
+ UNDEFINED, FALSE, TRUE
+ }
+
+ private Map<String, List<Element>> aggregatorElements = new
HashMap<String, List<Element>>();
+
+ private Map<String, List<Element>> renderkitElements = new
HashMap<String, List<Element>>();
+
+ private List<Element> simpleElements = new ArrayList<Element>();
+
+ private boolean hasProcessedConfigFiles;
+
+ private ThreeState metadataComplete = ThreeState.UNDEFINED;
+
+ private Comparator<Element> createElementsComparator() throws JDOMException {
+ List<String> elements = Arrays.asList(APPLICATION, ORDERING,
ABSOLUTE_ORDERING, FACTORY,
+ COMPONENT, CONVERTER, MANAGED_BEAN, NAME, NAVIGATION_RULE, REFERENCED_BEAN,
+ RENDER_KIT, LIFECYCLE, VALIDATOR, BEHAVIOR, FACES_CONFIG_EXTENSION,
+ /* lifecycle inners */ PHASE_LISTENER, LIFECYCLE_EXTENSION, /* lifecycle
inners end */
+ /* render-kit inners */ DESCRIPTION, DISPLAY_NAME, ICON, RENDER_KIT_ID,
+ RENDER_KIT_CLASS, RENDERER, CLIENT_BEHAVIOR_RENDERER, RENDER_KIT_EXTENSION /*
render-kit inners end*/);
+
+ Map<String, XPath> elementNameExpressions = new HashMap<String,
XPath>();
+
+ String componentTypeExpr = MessageFormat.format("./{0}:{1}|./{1}",
JAVAEE_PREFIX, COMPONENT_TYPE);
+ elementNameExpressions.put(COMPONENT, createXPath(componentTypeExpr));
+
+ String converterIdExpr = MessageFormat.format("./{0}:{1}|./{1}",
JAVAEE_PREFIX, CONVERTER_ID);
+ elementNameExpressions.put(CONVERTER, createXPath(converterIdExpr));
+
+ String validatorIdExpr = MessageFormat.format("./{0}:{1}|./{1}",
JAVAEE_PREFIX, VALIDATOR_ID);
+ elementNameExpressions.put(VALIDATOR, createXPath(validatorIdExpr));
+
+ String behaviorIdExpr = MessageFormat.format("./{0}:{1}|./{1}",
JAVAEE_PREFIX, BEHAVIOR_ID);
+ elementNameExpressions.put(BEHAVIOR, createXPath(behaviorIdExpr));
+
+ //renderer | client-behavior-renderer
+
+ return new ElementsComparator(JAVAEE_URI, elements, elementNameExpressions);
+ }
+
+ private void checkRootElement(Element element) {
+ if (!FACES_CONFIG.equals(element.getName())) {
+ throw new IllegalArgumentException("Root element name: " +
element.getName());
+ }
+
+ if (!isJavaEEOrDefaultNamespace(element)) {
+ throw new IllegalArgumentException("Root element namespace: " +
element.getNamespaceURI());
+ }
+ }
+
+ @Override
+ protected void processDocument(String resource, Document document, List relocators)
throws JDOMException {
+ hasProcessedConfigFiles = true;
+
+ Element rootElement = document.getRootElement();
+ checkRootElement(rootElement);
+
+ if (metadataComplete == ThreeState.UNDEFINED ||
Boolean.TRUE.equals(metadataComplete)) {
+ String metadataCompleteString =
rootElement.getAttributeValue(METADATA_COMPLETE);
+ if (!"true".equals(metadataCompleteString)) {
+ metadataComplete = ThreeState.FALSE;
+ }
+ }
+
+ Filter renderkitIdFilter = new ElementFilter().and(new
ElementFilter(RENDER_KIT_ID, JAVAEE_NAMESPACE).negate());
+ XPath renderKitIdXPath = createXPath(RENDER_KIT_ID_EXPRESSION);
+ List<Element> children = checkedList(rootElement.getChildren(),
Element.class);
+ for (Element child : children) {
+ if (!JAVAEE_URI.equals(child.getNamespaceURI())) {
+ simpleElements.add(child);
+ } else {
+ String name = child.getName();
+
+ if (UNHANDLED_ELEMENTS_NAME_SET.contains(name)) {
+ //TODO nick - log
+ continue;
+ }
+
+ if (AGGREGATOR_ELEMENTS_NAME_SET.contains(name)) {
+ List<Element> elementsList = aggregatorElements.get(name);
+ if (elementsList == null) {
+ elementsList = new ArrayList<Element>();
+ aggregatorElements.put(name, elementsList);
+ }
+
+ List<Element> aggregatorChildren =
checkedList(child.getChildren(), Element.class);
+ elementsList.addAll(cloneAndImportElements(aggregatorChildren));
+ } else if (RENDER_KIT.equals(name)) {
+ String renderkitId = renderKitIdXPath.valueOf(child);
+ if (renderkitId == null) {
+ renderkitId = "";
+ }
+
+ List<Element> elementsList =
renderkitElements.get(renderkitId);
+ if (elementsList == null) {
+ elementsList = new ArrayList<Element>();
+ renderkitElements.put(renderkitId, elementsList);
+ }
+
+ List<Element> renderkitChildren =
checkedList(child.getContent(renderkitIdFilter), Element.class);
+ elementsList.addAll(cloneAndImportElements(renderkitChildren));
+ } else {
+ simpleElements.add(cloneAndImportElement(child));
+ }
+ }
+ }
+ }
+
+ public boolean canTransformResource(String resource) {
+ String name = getMetaInfResourceName(resource);
+ if (name == null) {
+ return false;
+ }
+
+ return name.equals(FACES_CONFIG_FILE_NAME);
+ }
+
+ public boolean hasTransformedResource() {
+ return hasProcessedConfigFiles;
+ }
+
+ public void modifyOutputStream(JarOutputStream os) throws IOException {
+ try {
+ Comparator<Element> comparator;
+ try {
+ comparator = createElementsComparator();
+ } catch (JDOMException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+
+ Document document = new Document();
+ Element rootElement = new Element(FACES_CONFIG, JAVAEE_NAMESPACE);
+ rootElement.setAttribute(VERSION, CURRENT_VERSION);
+
+ if (metadataComplete != ThreeState.UNDEFINED) {
+ rootElement.setAttribute(METADATA_COMPLETE,
String.valueOf(metadataComplete == ThreeState.TRUE));
+ }
+ addSchemaLocation(rootElement,
"http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd");
+ document.addContent(rootElement);
+
+ List<Element> rootElementChildren = new ArrayList<Element>();
+ rootElementChildren.addAll(simpleElements);
+
+ for (Map.Entry<String, List<Element>> entry:
aggregatorElements.entrySet()) {
+ String elementName = entry.getKey();
+ List<Element> aggregatorElementChildren = entry.getValue();
+
+ Element aggregatorElement = new Element(elementName, JAVAEE_NAMESPACE);
+ rootElementChildren.add(aggregatorElement);
+
+ Collections.sort(aggregatorElementChildren, comparator);
+ aggregatorElement.addContent(aggregatorElementChildren);
+ }
+
+ for (Map.Entry<String, List<Element>> entry:
renderkitElements.entrySet()) {
+ String renderkitId = entry.getKey();
+ List<Element> renderkitElementChildren = entry.getValue();
+
+ Element renderkitElement = new Element(RENDER_KIT, JAVAEE_NAMESPACE);
+ rootElementChildren.add(renderkitElement);
+
+ if (renderkitId.length() != 0) {
+ Element renderkitIdElement = new Element(RENDER_KIT_ID,
JAVAEE_NAMESPACE);
+ renderkitIdElement.setText(renderkitId);
+ renderkitElementChildren.add(renderkitIdElement);
+ }
+
+ Collections.sort(renderkitElementChildren, comparator);
+ renderkitElement.addContent(renderkitElementChildren);
+ }
+
+ Collections.sort(rootElementChildren, comparator);
+
+ rootElement.addContent(rootElementChildren);
+
+ appendToStream(FACES_CONFIG_FILE_PATH, document, os);
+ } finally {
+ hasProcessedConfigFiles = false;
+ metadataComplete = ThreeState.UNDEFINED;
+
+ simpleElements.clear();
+ aggregatorElements.clear();
+ renderkitElements.clear();
+ }
+ }
+
+}
Added:
root/build/resources/trunk/faces-shade-transformers/src/main/java/org/richfaces/build/shade/resource/Taglib.java
===================================================================
---
root/build/resources/trunk/faces-shade-transformers/src/main/java/org/richfaces/build/shade/resource/Taglib.java
(rev 0)
+++
root/build/resources/trunk/faces-shade-transformers/src/main/java/org/richfaces/build/shade/resource/Taglib.java 2010-05-28
01:39:29 UTC (rev 17336)
@@ -0,0 +1,58 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.richfaces.build.shade.resource;
+
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class Taglib {
+
+ private String targetNamespace;
+
+ private String sourceNamespacesPattern;
+
+ public String getTargetNamespace() {
+ return targetNamespace;
+ }
+
+ public void setTargetNamespace(String targetNamespace) {
+ this.targetNamespace = targetNamespace;
+ }
+
+ public String getSourceNamespacesPattern() {
+ return sourceNamespacesPattern;
+ }
+
+ public void setSourceNamespacesPattern(String sourceNamespacesPattern) {
+ this.sourceNamespacesPattern = sourceNamespacesPattern;
+ }
+
+ public boolean matches(String namespace) {
+ if (sourceNamespacesPattern == null || sourceNamespacesPattern.length() == 0) {
+ return targetNamespace.equals(namespace);
+ }
+
+ return namespace.matches(sourceNamespacesPattern);
+ }
+}
Added:
root/build/resources/trunk/faces-shade-transformers/src/main/java/org/richfaces/build/shade/resource/TaglibXmlResourceTransformer.java
===================================================================
---
root/build/resources/trunk/faces-shade-transformers/src/main/java/org/richfaces/build/shade/resource/TaglibXmlResourceTransformer.java
(rev 0)
+++
root/build/resources/trunk/faces-shade-transformers/src/main/java/org/richfaces/build/shade/resource/TaglibXmlResourceTransformer.java 2010-05-28
01:39:29 UTC (rev 17336)
@@ -0,0 +1,214 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.richfaces.build.shade.resource;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.jar.JarOutputStream;
+
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jdom.filter.ElementFilter;
+import org.jdom.filter.Filter;
+import org.jdom.xpath.XPath;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class TaglibXmlResourceTransformer extends BaseFacesResourceTransformer {
+
+ private static final String ID = "id";
+ private static final String CURRENT_VERSION = "2.0";
+ private static final String VERSION = "version";
+ private static final String NAMESPACE = "namespace";
+ private static final String FUNCTION = "function";
+ private static final String TAG = "tag";
+ private static final String FUNCTION_NAME = "function-name";
+ private static final String TAG_NAME = "tag-name";
+ private static final String FACELET_TAGLIB = "facelet-taglib";
+
+ private static final String TAGLIB_XML_FILE_EXTENSION = ".taglib.xml";
+
+ private static final String NAMESPACE_EXPRESSION = MessageFormat.format(
+ "/{0}:{1}/{0}:{2}|/{1}/{2}", JAVAEE_PREFIX, FACELET_TAGLIB,
NAMESPACE);
+
+ private Map<String, List<Document>> tagLibraries = new HashMap<String,
List<Document>>();
+
+ private Map<String, Document> passThroughLibraries = new HashMap<String,
Document>();
+
+ private Taglib[] taglibs = new Taglib[0];
+
+ private Comparator<Element> createElementsComparator() throws JDOMException {
+ List<String> elements = Arrays.asList("description",
"display-name", "icon",
+ "library-class", NAMESPACE, "composite-library-name",
TAG, FUNCTION, "taglib-extension");
+
+ Map<String, XPath> elementNameExpressions = new HashMap<String,
XPath>();
+ String tagPathExpr = MessageFormat.format("./{0}:{1}|./{1}",
JAVAEE_PREFIX, TAG_NAME);
+ elementNameExpressions.put(TAG, createXPath(tagPathExpr));
+
+ String fnPathExpr = MessageFormat.format("./{0}:{1}|./{1}",
JAVAEE_PREFIX, FUNCTION_NAME);
+ elementNameExpressions.put(FUNCTION, createXPath(fnPathExpr));
+
+ return new ElementsComparator(JAVAEE_URI, elements, elementNameExpressions);
+ }
+
+ private String getShortName(String namespaceUri) {
+ int idx = namespaceUri.lastIndexOf('/');
+ if (idx < 0) {
+ return namespaceUri;
+ } else {
+ return namespaceUri.substring(idx + 1);
+ }
+ }
+
+ private Element createNamespaceElement(String namespaceUri) {
+ Element nsElement = new Element(NAMESPACE, JAVAEE_NAMESPACE);
+ nsElement.setText(namespaceUri);
+ return nsElement;
+ }
+
+ private String getFileName(String shortName) {
+ return META_INF_PATH + shortName + TAGLIB_XML_FILE_EXTENSION;
+ }
+
+ public boolean canTransformResource(String resource) {
+ String name = getMetaInfResourceName(resource);
+ return name != null && name.endsWith(TAGLIB_XML_FILE_EXTENSION);
+ }
+
+ private void checkRootElement(Element element) {
+ if (!FACELET_TAGLIB.equals(element.getName())) {
+ throw new IllegalArgumentException("Root element name: " +
element.getName());
+ }
+
+ if (!isJavaEEOrDefaultNamespace(element)) {
+ throw new IllegalArgumentException("Root element namespace: " +
element.getNamespaceURI());
+ }
+ }
+
+ public boolean hasTransformedResource() {
+ return !tagLibraries.isEmpty() || !passThroughLibraries.isEmpty();
+ }
+
+ public void modifyOutputStream(JarOutputStream os) throws IOException {
+ try {
+ for (Map.Entry<String, Document> entry :
passThroughLibraries.entrySet()) {
+ String resourceName = entry.getKey();
+ Document document = entry.getValue();
+
+ appendToStream(resourceName, document, os);
+ }
+ } finally {
+ passThroughLibraries.clear();
+ }
+
+ if (!tagLibraries.isEmpty()) {
+ Comparator<Element> elementsComparator;
+ try {
+ elementsComparator = createElementsComparator();
+ } catch (JDOMException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+
+ Filter filter = new ElementFilter().and(new ElementFilter(NAMESPACE,
JAVAEE_NAMESPACE).negate());
+
+ try {
+ for (Map.Entry<String, List<Document>> entry :
tagLibraries.entrySet()) {
+ String namespaceUri = entry.getKey();
+ String shortName = getShortName(namespaceUri);
+ List<Document> sourceDocuments = entry.getValue();
+
+ Document document = new org.jdom.Document();
+
+ Element rootElement = new Element(FACELET_TAGLIB, JAVAEE_NAMESPACE);
+ rootElement.setAttribute(VERSION, CURRENT_VERSION);
+ addSchemaLocation(rootElement,
"http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd");
+ rootElement.setAttribute(ID, shortName);
+
+ document.addContent(rootElement);
+
+ List<Element> elements = new ArrayList<Element>();
+ elements.add(createNamespaceElement(namespaceUri));
+
+ for (Document sourceDocument : sourceDocuments) {
+ Element sourceRootElement = sourceDocument.getRootElement();
+ checkRootElement(sourceRootElement);
+
+ List<Element> tagsContent =
checkedList(sourceRootElement.getContent(filter), Element.class);
+ for (Element tagElement: tagsContent) {
+ Element clonedElement = cloneAndImportElement(tagElement);
+ elements.add(clonedElement);
+ }
+ }
+
+ Collections.sort(elements, elementsComparator);
+ rootElement.addContent(elements);
+
+ String fileName = getFileName(shortName);
+ appendToStream(fileName, document, os);
+ }
+ } finally {
+ tagLibraries.clear();
+ }
+ }
+ }
+
+ @Override
+ protected void processDocument(String resource, Document document, List relocators)
throws JDOMException {
+ String namespaceUri = (String)
createXPath(NAMESPACE_EXPRESSION).valueOf(document);
+ if (namespaceUri == null || namespaceUri.length() == 0) {
+ passThroughLibraries.put(resource, document);
+ } else {
+ for (Taglib taglib : taglibs) {
+ if (taglib.matches(namespaceUri)) {
+ namespaceUri = taglib.getTargetNamespace();
+ break;
+ }
+ }
+
+ List<Document> documents = tagLibraries.get(namespaceUri);
+ if (documents == null) {
+ documents = new ArrayList<Document>();
+ tagLibraries.put(namespaceUri, documents);
+ }
+
+ documents.add(document);
+ }
+ }
+
+ public Taglib[] getTaglibs() {
+ return taglibs;
+ }
+
+ public void setTaglibs(Taglib[] taglibs) {
+ this.taglibs = taglibs;
+ }
+}
Modified: root/pom.xml
===================================================================
--- root/pom.xml 2010-05-28 01:07:12 UTC (rev 17335)
+++ root/pom.xml 2010-05-28 01:39:29 UTC (rev 17336)
@@ -33,6 +33,7 @@
<module>build/parent/tags/richfaces-parent-5</module>
<module>build/bom/trunk</module>
<!--<module>build/resources/trunk/checkstyle</module>-->
+ <module>build/resources/trunk/faces-shade-transformers</module>
<module>commons/${commons.svn.dir}</module>
<module>core/${core.svn.dir}</module>
<module>cdk/${cdk.svn.dir}</module>