You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by mo...@apache.org on 2017/09/01 13:17:20 UTC
[22/64] [partial] knox git commit: KNOX-998 - Refactoring save 1
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/json/JsonUrlRewriteStreamFilter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/json/JsonUrlRewriteStreamFilter.java b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/json/JsonUrlRewriteStreamFilter.java
new file mode 100644
index 0000000..bebc616
--- /dev/null
+++ b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/json/JsonUrlRewriteStreamFilter.java
@@ -0,0 +1,59 @@
+/**
+ * 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.knox.gateway.filter.rewrite.impl.json;
+
+import org.apache.commons.io.input.ReaderInputStream;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterContentDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriter;
+import org.apache.knox.gateway.filter.rewrite.spi.UrlRewriteStreamFilter;
+import org.apache.knox.gateway.util.urltemplate.Resolver;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class JsonUrlRewriteStreamFilter implements UrlRewriteStreamFilter {
+
+ private static String[] TYPES = new String[]{ "application/json", "text/json", "*/json" };
+ private static String[] NAMES = new String[]{ null };
+
+ @Override
+ public String[] getTypes() {
+ return TYPES;
+ }
+
+ @Override
+ public String[] getNames() {
+ return NAMES;
+ }
+
+ @Override
+ public InputStream filter(
+ InputStream stream,
+ String encoding,
+ UrlRewriter rewriter,
+ Resolver resolver,
+ UrlRewriter.Direction direction,
+ UrlRewriteFilterContentDescriptor config )
+ throws IOException {
+ return new ReaderInputStream(
+ new JsonUrlRewriteFilterReader(
+ new InputStreamReader( stream, encoding ), rewriter, resolver, direction, config ), encoding );
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/noop/NoOpUrlRewriteStreamFilter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/noop/NoOpUrlRewriteStreamFilter.java b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/noop/NoOpUrlRewriteStreamFilter.java
new file mode 100644
index 0000000..3db2bbd
--- /dev/null
+++ b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/noop/NoOpUrlRewriteStreamFilter.java
@@ -0,0 +1,55 @@
+/**
+ * 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.knox.gateway.filter.rewrite.impl.noop;
+
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterContentDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriter;
+import org.apache.knox.gateway.filter.rewrite.spi.UrlRewriteStreamFilter;
+import org.apache.knox.gateway.util.urltemplate.Resolver;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class NoOpUrlRewriteStreamFilter implements UrlRewriteStreamFilter {
+
+ private static String[] TYPES = new String[]{ null };
+ private static String[] NAMES = new String[]{ null };
+
+ @Override
+ public String[] getTypes() {
+ return TYPES;
+ }
+
+ @Override
+ public String[] getNames() {
+ return NAMES;
+ }
+
+ @Override
+ public InputStream filter(
+ InputStream stream,
+ String encoding,
+ UrlRewriter rewriter,
+ Resolver resolver,
+ UrlRewriter.Direction direction,
+ UrlRewriteFilterContentDescriptor config )
+ throws IOException {
+ return stream;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/xml/XmlFilterReader.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/xml/XmlFilterReader.java b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/xml/XmlFilterReader.java
new file mode 100644
index 0000000..b5c2593
--- /dev/null
+++ b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/xml/XmlFilterReader.java
@@ -0,0 +1,643 @@
+/**
+ * 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.knox.gateway.filter.rewrite.impl.xml;
+
+import org.apache.commons.lang3.StringEscapeUtils;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterApplyDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterBufferDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterContentDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterDetectDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterGroupDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterPathDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterScopeDescriptor;
+import org.apache.knox.gateway.filter.rewrite.i18n.UrlRewriteMessages;
+import org.apache.knox.gateway.filter.rewrite.i18n.UrlRewriteResources;
+import org.apache.knox.gateway.i18n.messages.MessagesFactory;
+import org.apache.knox.gateway.i18n.resources.ResourcesFactory;
+import org.apache.knox.gateway.util.XmlUtils;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.Characters;
+import javax.xml.stream.events.Comment;
+import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.Namespace;
+import javax.xml.stream.events.StartDocument;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.Iterator;
+import java.util.Stack;
+import java.util.regex.Pattern;
+
+public abstract class XmlFilterReader extends Reader {
+
+ private static final UrlRewriteResources RES = ResourcesFactory.get( UrlRewriteResources.class );
+
+ private static final String DEFAULT_XML_VERSION = "1.0";
+
+ private static final UrlRewriteMessages LOG = MessagesFactory.get( UrlRewriteMessages.class );
+ private static final UrlRewriteFilterPathDescriptor.Compiler<XPathExpression> XPATH_COMPILER = new XmlPathCompiler();
+ private static final UrlRewriteFilterPathDescriptor.Compiler<Pattern> REGEX_COMPILER = new RegexCompiler();
+
+ private Reader reader;
+ private UrlRewriteFilterContentDescriptor config;
+ private int offset;
+ private StringWriter writer;
+ private StringBuffer buffer;
+ private XMLInputFactory factory;
+ private XMLEventReader parser;
+ private Document document;
+ private Stack<Level> stack;
+ private boolean isEmptyElement;
+
+ protected XmlFilterReader( Reader reader, UrlRewriteFilterContentDescriptor config ) throws IOException, XMLStreamException {
+ this.reader = reader;
+ this.config = config;
+ writer = new StringWriter();
+ buffer = writer.getBuffer();
+ offset = 0;
+ document = null;
+ stack = new Stack<Level>();
+ isEmptyElement = false;
+ factory = XMLInputFactory.newFactory();
+ //KNOX-620 factory.setProperty( XMLConstants.ACCESS_EXTERNAL_DTD, "false" );
+ //KNOX-620 factory.setProperty( XMLConstants.ACCESS_EXTERNAL_SCHEMA, "false" );
+ factory.setProperty( "javax.xml.stream.isReplacingEntityReferences", Boolean.FALSE );
+ factory.setProperty("http://java.sun.com/xml/stream/"
+ + "properties/report-cdata-event", Boolean.TRUE);
+ parser = factory.createXMLEventReader( reader );
+ }
+
+ protected abstract String filterAttribute( QName elementName, QName attributeName, String attributeValue, String ruleName );
+
+ protected abstract String filterText( QName elementName, String text, String ruleName );
+
+ @Override
+ public int read( char[] destBuffer, int destOffset, int destCount ) throws IOException {
+ int count = 0;
+ int available = buffer.length() - offset;
+
+ if( available == 0 ) {
+ if( parser.hasNext() ) {
+ try {
+ XMLEvent event = parser.nextEvent();
+ processEvent( event );
+ } catch( IOException e ) {
+ throw e;
+ } catch( RuntimeException e ) {
+ throw e;
+ } catch ( Exception e ) {
+ throw new RuntimeException( e );
+ }
+ available = buffer.length() - offset;
+ } else {
+ count = -1;
+ }
+ }
+
+ if( available > 0 ) {
+ count = Math.min( destCount, available );
+ buffer.getChars( offset, offset + count, destBuffer, destOffset );
+ offset += count;
+ if( offset == buffer.length() ) {
+ offset = 0;
+ buffer.setLength( 0 );
+ }
+ }
+ return count;
+ }
+
+ private void processEvent( XMLEvent event ) throws ParserConfigurationException, XPathExpressionException, IOException, XMLStreamException {
+ int type = event.getEventType();
+ switch( type ) {
+ case XMLEvent.START_DOCUMENT:
+ processStartDocument( (StartDocument)event );
+ break;
+ case XMLEvent.END_DOCUMENT:
+ processEndDocument();
+ break;
+ case XMLEvent.START_ELEMENT:
+ if( parser.peek().getEventType() == XMLEvent.END_ELEMENT )
+ isEmptyElement = true;
+ processStartElement( event.asStartElement());
+ break;
+ case XMLEvent.END_ELEMENT:
+ processEndElement( event.asEndElement() );
+ isEmptyElement = false;
+ break;
+ case XMLEvent.CHARACTERS:
+ case XMLEvent.CDATA:
+ case XMLEvent.SPACE:
+ processCharacters( event.asCharacters() );
+ break;
+ case XMLEvent.COMMENT:
+ processComment( (Comment)event );
+ break;
+ case XMLEvent.DTD:
+ case XMLEvent.NAMESPACE:
+ case XMLEvent.ATTRIBUTE:
+ case XMLEvent.ENTITY_REFERENCE:
+ case XMLEvent.ENTITY_DECLARATION:
+ case XMLEvent.NOTATION_DECLARATION:
+ case XMLEvent.PROCESSING_INSTRUCTION:
+ default:
+ // Fail if we run into any of these for now.
+ throw new IllegalStateException( Integer.toString( type ) );
+ }
+ }
+
+ private void processStartDocument( StartDocument event ) throws ParserConfigurationException {
+ //System.out.println( "SD=" + event );
+ String s;
+
+ document = XmlUtils.createDocument( false );
+ pushLevel( null, event, document, document, config );
+
+ writer.write( "<?xml" );
+
+ s = event.getVersion();
+ if( s == null ) {
+ s = DEFAULT_XML_VERSION;
+ }
+ writer.write( " version=\"");
+ writer.write( s );
+ writer.write( "\"" );
+
+ s = event.getCharacterEncodingScheme();
+ if( s != null ) {
+ writer.write( " encoding=\"");
+ writer.write( s );
+ writer.write( "\"" );
+ }
+
+ writer.write( " standalone=\"");
+ writer.write( event.isStandalone() ? "yes" : "no" );
+ writer.write( "\"" );
+
+ writer.write( "?>" );
+ }
+
+ private void processEndDocument() {
+ stack.clear();
+ document = null;
+ }
+
+ private void processStartElement( StartElement event ) throws XPathExpressionException {
+ //System.out.println( "SE=" + event );
+
+ // Create a new "empty" element and add it to the document.
+ Element element = bufferElement( event );
+ Level parent = stack.peek();
+ parent.node.appendChild( element );
+
+ // If already buffering just continue to do so.
+ // Note: Don't currently support nested buffer or scope descriptors.
+ if( currentlyBuffering() ) {
+ pushLevel( parent, event, element, parent.scopeNode, parent.scopeConfig );
+ bufferAttributes( event, element );
+ // Else not currently buffering
+ } else {
+ // See if there is a matching path descriptor in the current scope.
+ UrlRewriteFilterPathDescriptor descriptor = pickFirstMatchingPath( parent );
+ if( descriptor != null ) {
+ // If this is a buffer descriptor then switch to buffering and buffer the attributes.
+ if( descriptor instanceof UrlRewriteFilterBufferDescriptor ) {
+ pushLevel( parent, event, element, element, (UrlRewriteFilterBufferDescriptor)descriptor );
+ bufferAttributes( event, element );
+ // Otherwise if this is a scope descriptor then change the scope and stream the attributes.
+ } else if( descriptor instanceof UrlRewriteFilterScopeDescriptor ) {
+ pushLevel( parent, event, element, element, (UrlRewriteFilterScopeDescriptor)descriptor );
+ streamElement( event, element );
+ // Else found an unexpected matching path.
+ } else {
+ // This is likely because there is an <apply> targeted at the text of an element.
+ // That "convenience" config will be taken care of in the streamElement() processing.
+ pushLevel( parent, event, element, parent.scopeNode, parent.scopeConfig );
+ streamElement( event, element );
+ }
+ // If there is no matching path descriptor then continue streaming.
+ } else {
+ pushLevel( parent, event, element, parent.scopeNode, parent.scopeConfig );
+ streamElement( event, element );
+ }
+ }
+ }
+
+ private void processEndElement( EndElement event ) throws XPathExpressionException, IOException {
+ //System.out.println( "EE=" + event );
+ boolean buffering = currentlyBuffering();
+ Level child = stack.pop();
+ if( buffering ) {
+ if( child.node == child.scopeNode ) {
+ processBufferedElement( child );
+ }
+ } else {
+ if( ! isEmptyElement ) {
+ QName n = event.getName();
+ writer.write( "</" );
+ String p = n.getPrefix();
+ if( p != null && !p.isEmpty() ) {
+ writer.write( p );
+ writer.write( ":" );
+ }
+ writer.write( n.getLocalPart() );
+ writer.write( ">" );
+ }
+ child.node.getParentNode().removeChild( child.node );
+ }
+ }
+
+ private Element bufferElement( StartElement event ) {
+ QName qname = event.getName();
+ String prefix = qname.getPrefix();
+ String uri = qname.getNamespaceURI();
+ Element element;
+ if( uri == null || uri.isEmpty() ) {
+ element = document.createElement( qname.getLocalPart() );
+ } else {
+ element = document.createElementNS( qname.getNamespaceURI(), qname.getLocalPart() );
+ if( prefix != null && !prefix.isEmpty() ) {
+ element.setPrefix( prefix );
+ }
+ }
+ // Always need to buffer the namespaces regardless of what else happens so that XPath will work on attributes
+ // namespace qualified attributes.
+ bufferNamespaces( event, element );
+ return element;
+ }
+
+ private void bufferNamespaces( StartElement event, Element element ) {
+ Iterator namespaces = event.getNamespaces();
+ while( namespaces.hasNext() ) {
+ Namespace namespace = (Namespace)namespaces.next();
+ if( namespace.isDefaultNamespaceDeclaration() ) {
+ element.setAttribute( "xmlns", namespace.getNamespaceURI() );
+ } else {
+ element.setAttribute( "xmlns:" + namespace.getPrefix(), namespace.getNamespaceURI() );
+ }
+ }
+ }
+
+ private void streamElement( StartElement event, Element element ) throws XPathExpressionException {
+ writer.write( "<" );
+ QName qname = event.getName();
+ String prefix = event.getName().getPrefix();
+ if( prefix != null && !prefix.isEmpty() ) {
+ writer.write( prefix );
+ writer.write( ":" );
+ }
+ writer.write( qname.getLocalPart() );
+ streamNamespaces( event );
+ streamAttributes( event, element );
+ if( isEmptyElement ) {
+ writer.write("/>");
+ } else {
+ writer.write(">");
+ }
+ }
+
+ private void processBufferedElement( Level level, UrlRewriteFilterGroupDescriptor config ) throws XPathExpressionException {
+ for( UrlRewriteFilterPathDescriptor selector : config.getSelectors() ) {
+ if( selector instanceof UrlRewriteFilterApplyDescriptor ) {
+ XPathExpression path = (XPathExpression)selector.compiledPath( XPATH_COMPILER );
+ Object node = path.evaluate( level.scopeNode, XPathConstants.NODE );
+ if( node != null ) {
+ UrlRewriteFilterApplyDescriptor apply = (UrlRewriteFilterApplyDescriptor)selector;
+ if( node instanceof Element ) {
+ Element element = (Element)node;
+ String value = element.getTextContent();
+ value = filterText( extractQName( element ), value, apply.rule() );
+ element.setTextContent( value );
+ } else if( node instanceof Text ) {
+ Text text = (Text)node;
+ String value = text.getWholeText();
+ value = filterText( extractQName( text.getParentNode() ), value, apply.rule() );
+ text.replaceWholeText( value );
+ } else if( node instanceof Attr ) {
+ Attr attr = (Attr)node;
+ String value = attr.getValue();
+ value = filterAttribute( extractQName( attr.getOwnerElement() ), extractQName( attr ), value, apply.rule() );
+ attr.setValue( value );
+ } else {
+ throw new IllegalArgumentException( RES.unexpectedSelectedNodeType( node ) );
+ }
+ }
+ } else if( selector instanceof UrlRewriteFilterDetectDescriptor) {
+ XPathExpression path = (XPathExpression)selector.compiledPath( XPATH_COMPILER );
+ Object node = path.evaluate( level.scopeNode, XPathConstants.NODE );
+ if( node != null ) {
+ UrlRewriteFilterDetectDescriptor detect = (UrlRewriteFilterDetectDescriptor)selector;
+ String value = null;
+ if( node instanceof Element ) {
+ Element element = (Element)node;
+ value = element.getTextContent();
+ } else if( node instanceof Text ) {
+ Text text = (Text)node;
+ value = text.getWholeText();
+ } else if( node instanceof Attr ) {
+ Attr attr = (Attr)node;
+ value = attr.getValue();
+ } else {
+ throw new IllegalArgumentException( RES.unexpectedSelectedNodeType( node ) );
+ }
+ if( detect.compiledValue( REGEX_COMPILER ).matcher( value ).matches() ) {
+ processBufferedElement( level, detect );
+ }
+ }
+ } else {
+ throw new IllegalArgumentException( RES.unexpectedRewritePathSelector( selector ) );
+ }
+ }
+ }
+
+ private void processBufferedElement( Level level ) throws XPathExpressionException, IOException {
+ processBufferedElement( level, level.scopeConfig );
+ writeBufferedElement( level.node, writer );
+ }
+
+ private QName extractQName( Node node ) {
+ QName qname;
+ String localName = node.getLocalName();
+ if( localName == null ) {
+ qname = new QName( node.getNodeName() );
+ } else {
+ if ( node.getPrefix() == null ) {
+ qname = new QName( node.getNamespaceURI(), localName );
+ } else {
+ qname = new QName( node.getNamespaceURI(), localName, node.getPrefix() );
+ }
+
+ }
+ return qname;
+ }
+
+ private void bufferAttributes( StartElement event, Element element ) {
+ Iterator attributes = event.getAttributes();
+ while( attributes.hasNext() ) {
+ Attribute attribute = (Attribute)attributes.next();
+ bufferAttribute( element, attribute );
+ }
+ }
+
+ private Attr bufferAttribute( Element element, Attribute attribute ) {
+ QName name = attribute.getName();
+ String prefix = name.getPrefix();
+ String uri = name.getNamespaceURI();
+ Attr node;
+ if( uri == null || uri.isEmpty() ) {
+ node = document.createAttribute( name.getLocalPart() );
+ element.setAttributeNode( node );
+ } else {
+ node = document.createAttributeNS( uri, name.getLocalPart() );
+ if( prefix != null && !prefix.isEmpty() ) {
+ node.setPrefix( prefix );
+ }
+ element.setAttributeNodeNS( node );
+ }
+ node.setTextContent( attribute.getValue() );
+ return node;
+ }
+
+ private void streamNamespaces( StartElement event ) {
+ Iterator i = event.getNamespaces();
+ while( i.hasNext() ) {
+ Namespace ns = (Namespace)i.next();
+ writer.write( " xmlns" );
+ if( !ns.isDefaultNamespaceDeclaration() ) {
+ writer.write( ":" );
+ writer.write( ns.getPrefix() );
+ }
+ writer.write( "=\"" );
+ writer.write( ns.getNamespaceURI() );
+ writer.write( "\"" );
+ }
+ }
+
+ private void streamAttributes( StartElement event, Element element ) throws XPathExpressionException {
+ Iterator i = event.getAttributes();
+ while( i.hasNext() ) {
+ Attribute attribute = (Attribute)i.next();
+ streamAttribute( element, attribute );
+ }
+ }
+
+ private void streamAttribute( Element element, Attribute attribute ) throws XPathExpressionException {
+ Attr node;
+ QName name = attribute.getName();
+ String prefix = name.getPrefix();
+ String uri = name.getNamespaceURI();
+ if( uri == null || uri.isEmpty() ) {
+ node = document.createAttribute( name.getLocalPart() );
+ element.setAttributeNode( node );
+ } else {
+ node = document.createAttributeNS( uri, name.getLocalPart() );
+ if( prefix != null && !prefix.isEmpty() ) {
+ node.setPrefix( prefix );
+ }
+ element.setAttributeNodeNS( node );
+ }
+
+ String value = attribute.getValue();
+ Level level = stack.peek();
+ if( ( level.scopeConfig ) == null || ( level.scopeConfig.getSelectors().isEmpty() ) ) {
+ value = filterAttribute( null, attribute.getName(), value, null );
+ node.setValue( value );
+ } else {
+ UrlRewriteFilterPathDescriptor path = pickFirstMatchingPath( level );
+ if( path instanceof UrlRewriteFilterApplyDescriptor ) {
+ String rule = ((UrlRewriteFilterApplyDescriptor)path).rule();
+ value = filterAttribute( null, attribute.getName(), value, rule );
+ node.setValue( value );
+ }
+ }
+
+ //dump( document );
+
+ if( prefix == null || prefix.isEmpty() ) {
+ writer.write( " " );
+ writer.write( name.getLocalPart() );
+ } else {
+ writer.write( " " );
+ writer.write( prefix );
+ writer.write( ":" );
+ writer.write( name.getLocalPart() );
+ }
+ writer.write( "=\"" );
+ writer.write( value );
+ writer.write( "\"" );
+ element.removeAttributeNode( node );
+ }
+
+ private void processCharacters( Characters event ) throws XPathExpressionException {
+ //System.out.println( "T[" + event.isCData() + "," + event.isWhiteSpace() + "," + event.isIgnorableWhiteSpace() + "]=" + event );
+ Level level = stack.peek();
+ Node node = stack.peek().node;
+ if( event.isCData() ) {
+ node.appendChild( document.createCDATASection( event.getData() ) );
+ } else {
+ node.appendChild( document.createTextNode( event.getData() ) );
+ }
+ if( !currentlyBuffering() ) {
+ String value = event.getData();
+ if( !event.isWhiteSpace() ) {
+ if( level.scopeConfig == null || level.scopeConfig.getSelectors().isEmpty() ) {
+ value = filterText( extractQName( node ), value, null );
+ } else {
+ UrlRewriteFilterPathDescriptor path = pickFirstMatchingPath( level );
+ if( path instanceof UrlRewriteFilterApplyDescriptor ) {
+ String rule = ((UrlRewriteFilterApplyDescriptor)path).rule();
+ value = filterText( extractQName( node ), value, rule );
+ }
+ }
+ }
+ if( event.isCData() ) {
+ writer.write( "<![CDATA[" );
+ writer.write( value );
+ writer.write( "]]>" );
+ } else {
+ writer.write( StringEscapeUtils.escapeXml( value ) );
+ }
+ }
+ }
+
+ private void processComment( Comment event ) {
+ //System.out.println( "C=" + event );
+ if( currentlyBuffering() ) {
+ stack.peek().node.appendChild( document.createComment( event.getText() ) );
+ } else {
+ writer.write( "<!--" );
+ writer.write( event.getText() );
+ writer.write( "-->" );
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ try {
+ parser.close();
+ } catch( XMLStreamException e ) {
+ throw new IOException( e );
+ }
+ reader.close();
+ writer.close();
+ stack.clear();
+ }
+
+ protected UrlRewriteFilterPathDescriptor pickFirstMatchingPath( Level level ) {
+ UrlRewriteFilterPathDescriptor match = null;
+ if( level.scopeConfig != null ) {
+ for( UrlRewriteFilterPathDescriptor selector : level.scopeConfig.getSelectors() ) {
+ try {
+ XPathExpression path = (XPathExpression)selector.compiledPath( XPATH_COMPILER );
+ Object node = path.evaluate( level.scopeNode, XPathConstants.NODE );
+ if( node != null ) {
+ match = selector;
+ break;
+ }
+ } catch( XPathExpressionException e ) {
+ throw new IllegalArgumentException( selector.path(), e );
+ }
+ }
+ }
+ return match;
+ }
+
+ private boolean currentlyBuffering() {
+ return stack.peek().buffered;
+ }
+
+ private Level pushLevel( Level parent, XMLEvent event, Node node, Node scopeNode, UrlRewriteFilterGroupDescriptor scopeConfig ) {
+ Level level = new Level( parent, event, node, scopeNode, scopeConfig );
+ stack.push( level );
+ return level;
+ }
+
+ private static class Level {
+// private Level parent;
+// private XMLEvent event;
+ private Node node;
+ private UrlRewriteFilterGroupDescriptor scopeConfig;
+ private Node scopeNode;
+ private boolean buffered;
+
+ private Level( Level parent, XMLEvent event, Node node, Node scopeNode, UrlRewriteFilterGroupDescriptor scopeConfig ) {
+// this.parent = parent;
+// this.event = event;
+ this.node = node;
+ this.scopeConfig = scopeConfig;
+ this.scopeNode = scopeNode;
+ this.buffered = ( ( parent != null ) && parent.buffered ) ||
+ ( ( scopeConfig != null ) && ( scopeConfig instanceof UrlRewriteFilterBufferDescriptor ) );
+ }
+ }
+
+ private static class XmlPathCompiler implements UrlRewriteFilterPathDescriptor.Compiler<XPathExpression> {
+ private static XPath XPATH = XPathFactory.newInstance().newXPath();
+ @Override
+ public XPathExpression compile( String expression, XPathExpression compiled ) {
+ try {
+ return XPATH.compile( expression );
+ } catch( XPathExpressionException e ) {
+ throw new IllegalArgumentException( e );
+ }
+ }
+ }
+
+ private static class RegexCompiler implements UrlRewriteFilterPathDescriptor.Compiler<Pattern> {
+ @Override
+ public Pattern compile( String expression, Pattern compiled ) {
+ if( compiled != null ) {
+ return compiled;
+ } else {
+ return Pattern.compile( expression );
+ }
+ }
+ }
+
+ private static final void writeBufferedElement( Node node, Writer writer ) throws IOException {
+ try {
+ Transformer t = XmlUtils.getTransformer( false, false, 0, true );
+ t.transform( new DOMSource( node ), new StreamResult( writer ) );
+ } catch( TransformerException e ) {
+ throw new IOException( e );
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/xml/XmlRewriteRulesDigester.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/xml/XmlRewriteRulesDigester.java b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/xml/XmlRewriteRulesDigester.java
new file mode 100644
index 0000000..2c5b3c6
--- /dev/null
+++ b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/xml/XmlRewriteRulesDigester.java
@@ -0,0 +1,239 @@
+/**
+ * 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.knox.gateway.filter.rewrite.impl.xml;
+
+import org.apache.commons.digester3.Digester;
+import org.apache.commons.digester3.Rule;
+import org.apache.commons.digester3.SetPropertiesRule;
+import org.apache.commons.digester3.binder.AbstractRulesModule;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterContentDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterGroupDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterPathDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFlowDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFunctionDescriptorFactory;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteRuleDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteRulesDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteRulesDescriptorFactory;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteStepDescriptorFactory;
+import org.apache.knox.gateway.filter.rewrite.impl.UrlRewriteFilterApplyDescriptorImpl;
+import org.apache.knox.gateway.filter.rewrite.impl.UrlRewriteFilterBufferDescriptorImpl;
+import org.apache.knox.gateway.filter.rewrite.impl.UrlRewriteFilterDetectDescriptorImpl;
+import org.apache.knox.gateway.filter.rewrite.impl.UrlRewriteFilterScopeDescriptorImpl;
+import org.xml.sax.Attributes;
+
+public class XmlRewriteRulesDigester extends AbstractRulesModule implements XmlRewriteRulesTags {
+
+ @Override
+ protected void configure() {
+ forPattern( ROOT ).addRule( new RulesFactory() );
+ forPattern( ROOT ).addRule( new SetPropertiesRule() );
+
+ for( String name : UrlRewriteFunctionDescriptorFactory.getNames() ) {
+ forPattern( ROOT + "/" + FUNCTIONS + "/" + name ).addRule( new FunctionFactory() );
+ forPattern( ROOT + "/" + FUNCTIONS + "/" + name ).addRule( new SetPropertiesRule() );
+ }
+
+ forPattern( ROOT + "/" + RULE ).addRule( new RuleFactory() );
+ forPattern( ROOT + "/" + RULE ).addRule( new SetPropertiesRule() );
+ for( String type : UrlRewriteStepDescriptorFactory.getTypes() ) {
+ forPattern( "*/" + type ).addRule( new StepFactory() );
+ forPattern( "*/" + type ).addRule( new SetPropertiesRule() );
+ }
+
+ forPattern( ROOT + "/" + FILTER ).addRule( new FilterFactory() );
+ forPattern( ROOT + "/" + FILTER ).addRule( new SetPropertiesRule() );
+ forPattern( ROOT + "/" + FILTER + "/" + CONTENT ).addRule( new FilterContentFactory() );
+ forPattern( ROOT + "/" + FILTER + "/" + CONTENT ).addRule( new SetPropertiesRule() );
+
+ forPattern( ROOT + "/" + FILTER + "/" + CONTENT + "/*/" + APPLY ).addRule( new FilterApplyFactory() );
+ forPattern( ROOT + "/" + FILTER + "/" + CONTENT + "/*/" + APPLY ).addRule( new SetPropertiesRule() );
+
+ forPattern( ROOT + "/" + FILTER + "/" + CONTENT + "/" + SCOPE ).addRule( new FilterScopeFactory() );
+ forPattern( ROOT + "/" + FILTER + "/" + CONTENT + "/" + SCOPE ).addRule( new SetPropertiesRule() );
+
+ forPattern( ROOT + "/" + FILTER + "/" + CONTENT + "/" + BUFFER ).addRule( new FilterBufferFactory() );
+ forPattern( ROOT + "/" + FILTER + "/" + CONTENT + "/" + BUFFER ).addRule( new SetPropertiesRule() );
+
+ forPattern( ROOT + "/" + FILTER + "/" + CONTENT + "/" + BUFFER + "/" + DETECT ).addRule( new FilterDetectFactory() );
+ forPattern( ROOT + "/" + FILTER + "/" + CONTENT + "/" + BUFFER + "/" + DETECT ).addRule( new SetPropertiesRule() );
+
+// forPattern( "*/" + MATCH ).addRule( new MatchFactory() );
+// forPattern( "*/" + MATCH ).addRule( new SetPropertiesRule() );
+// forPattern( "*/" + CHECK ).addRule( new CheckFactory() );
+// forPattern( "*/" + CHECK ).addRule( new SetPropertiesRule() );
+// forPattern( "*/" + CONTROL ).addRule( new ControlFactory() );
+// forPattern( "*/" + CONTROL ).addRule( new SetPropertiesRule() );
+// forPattern( "*/" + ACTION ).addRule( new ActionFactory() );
+// forPattern( "*/" + ACTION ).addRule( new SetPropertiesRule() );
+ }
+
+ private static class RulesFactory extends FactoryRule {
+ @Override
+ public Object create( String namespace, String name, Attributes attributes ) {
+ return UrlRewriteRulesDescriptorFactory.create();
+ }
+ }
+
+ private static class RuleFactory extends Rule {
+ @Override
+ public void begin( String namespace, String name, Attributes attributes ) throws Exception {
+ Digester digester = getDigester();
+ UrlRewriteRulesDescriptor rules = digester.peek();
+ UrlRewriteRuleDescriptor rule = rules.newRule();
+ getDigester().push( rule );
+ }
+
+ @Override
+ public void end( String namespace, String name ) throws Exception {
+ Digester digester = getDigester();
+ UrlRewriteRuleDescriptor rule = digester.pop();
+ UrlRewriteRulesDescriptor rules = digester.peek();
+ rules.addRule( rule );
+ }
+ }
+
+ private static class StepFactory extends FactoryRule {
+ @Override
+ public Object create( String namespace, String name, Attributes attributes ) {
+ UrlRewriteFlowDescriptor flow = getDigester().peek();
+ return flow.addStep( name );
+ }
+ }
+
+ private static class FunctionFactory extends FactoryRule {
+ @Override
+ public Object create( String namespace, String name, Attributes attributes ) {
+ UrlRewriteRulesDescriptor rules = getDigester().peek();
+ return rules.addFunction( name );
+ }
+ }
+
+ private static class FilterFactory extends FactoryRule {
+ @Override
+ public Object create( String namespace, String name, Attributes attributes ) {
+ UrlRewriteRulesDescriptor parent = getDigester().peek();
+ return parent.addFilter( attributes.getValue( "name" ) );
+ }
+ }
+
+ private static class FilterContentFactory extends FactoryRule {
+ @Override
+ public Object create( String namespace, String name, Attributes attributes ) {
+ UrlRewriteFilterDescriptor parent = getDigester().peek();
+ UrlRewriteFilterContentDescriptor descriptor = parent.addContent( attributes.getValue( "type" ) );
+ if (attributes.getValue( "asType" ) != null) {
+ descriptor = descriptor.asType(attributes.getValue( "asType" ));
+ }
+ return descriptor;
+ }
+ }
+
+ private static class FilterApplyFactory extends FactoryRule {
+ @Override
+ public Object create( String namespace, String name, Attributes attributes ) {
+ UrlRewriteFilterGroupDescriptor parent = getDigester().peek();
+ UrlRewriteFilterPathDescriptor child = new UrlRewriteFilterApplyDescriptorImpl();
+ child.path( attributes.getValue( "path" ) );
+ parent.addSelector( child );
+ return child;
+ }
+ }
+
+ private static class FilterScopeFactory extends FactoryRule {
+ @Override
+ public Object create( String namespace, String name, Attributes attributes ) {
+ UrlRewriteFilterGroupDescriptor parent = getDigester().peek();
+ UrlRewriteFilterPathDescriptor child = new UrlRewriteFilterScopeDescriptorImpl();
+ child.path( attributes.getValue( "path" ) );
+ parent.addSelector( child );
+ return child;
+ }
+ }
+
+ private static class FilterBufferFactory extends FactoryRule {
+ @Override
+ public Object create( String namespace, String name, Attributes attributes ) {
+ UrlRewriteFilterGroupDescriptor parent = getDigester().peek();
+ UrlRewriteFilterPathDescriptor child = new UrlRewriteFilterBufferDescriptorImpl();
+ child.path( attributes.getValue( "path" ) );
+ parent.addSelector( child );
+ return child;
+ }
+ }
+
+ private static class FilterDetectFactory extends FactoryRule {
+ @Override
+ public Object create( String namespace, String name, Attributes attributes ) {
+ UrlRewriteFilterGroupDescriptor parent = getDigester().peek();
+ UrlRewriteFilterPathDescriptor child = new UrlRewriteFilterDetectDescriptorImpl();
+ child.path( attributes.getValue( "path" ) );
+ parent.addSelector( child );
+ return child;
+ }
+ }
+
+// private static class MatchFactory extends FactoryRule {
+// @Override
+// public Object create( String namespace, String name, Attributes attributes ) {
+// UrlRewriteRuleDescriptor rule = getDigester().peek();
+// return rule.addMatch();
+// }
+// }
+//
+// private static class CheckFactory extends FactoryRule {
+// @Override
+// public Object create( String namespace, String name, Attributes attributes ) {
+// UrlRewriteRuleDescriptor rule = getDigester().peek();
+// return rule.addCheck();
+// }
+// }
+//
+// private static class ActionFactory extends FactoryRule {
+// @Override
+// public Object create( String namespace, String name, Attributes attributes ) {
+// UrlRewriteRuleDescriptor rule = getDigester().peek();
+// return rule.addAction();
+// }
+// }
+//
+// private static class ControlFactory extends FactoryRule {
+// @Override
+// public Object create( String namespace, String name, Attributes attributes ) {
+// UrlRewriteRuleDescriptor rule = getDigester().peek();
+// return rule.addControl();
+// }
+// }
+
+ private static abstract class FactoryRule extends Rule {
+
+ protected abstract Object create( String namespace, String name, Attributes attributes );
+
+ @Override
+ public void begin( String namespace, String name, Attributes attributes ) throws Exception {
+ getDigester().push( create( namespace, name, attributes ) );
+ }
+
+ @Override
+ public void end( String namespace, String name ) throws Exception {
+ getDigester().pop();
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/xml/XmlRewriteRulesTags.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/xml/XmlRewriteRulesTags.java b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/xml/XmlRewriteRulesTags.java
new file mode 100644
index 0000000..872521a
--- /dev/null
+++ b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/xml/XmlRewriteRulesTags.java
@@ -0,0 +1,54 @@
+/**
+ * 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.knox.gateway.filter.rewrite.impl.xml;
+
+/**
+ * <rules>
+ * <filter name="">
+ * <content type="json"> == <scope path="$"/>
+ * <apply/>
+ * <select>
+ * <choice>
+ * <apply/>
+ * </choice>
+ * </select>
+ * </content>
+ * </filter>
+ * </rules>
+ */
+public interface XmlRewriteRulesTags {
+
+ static final String ROOT = "rules";
+
+ static final String FUNCTIONS = "functions";
+
+ static final String RULE = "rule";
+
+// static final String MATCH = "match";
+// static final String CHECK = "check";
+// static final String CONTROL = "control";
+// static final String ACTION = "action";
+
+ static final String FILTER = "filter";
+ static final String CONTENT = "content";
+ static final String SCOPE = "scope";
+ static final String BUFFER = "buffer";
+ static final String DETECT = "detect";
+ static final String APPLY = "apply";
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/xml/XmlUrlRewriteFilterReader.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/xml/XmlUrlRewriteFilterReader.java b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/xml/XmlUrlRewriteFilterReader.java
new file mode 100644
index 0000000..68d13db
--- /dev/null
+++ b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/xml/XmlUrlRewriteFilterReader.java
@@ -0,0 +1,80 @@
+/**
+ * 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.knox.gateway.filter.rewrite.impl.xml;
+
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterContentDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriter;
+import org.apache.knox.gateway.filter.rewrite.i18n.UrlRewriteMessages;
+import org.apache.knox.gateway.i18n.messages.MessagesFactory;
+import org.apache.knox.gateway.util.urltemplate.Parser;
+import org.apache.knox.gateway.util.urltemplate.Resolver;
+import org.apache.knox.gateway.util.urltemplate.Template;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.stream.XMLStreamException;
+import java.io.IOException;
+import java.io.Reader;
+import java.net.URISyntaxException;
+
+public class XmlUrlRewriteFilterReader extends XmlFilterReader {
+
+ private static final UrlRewriteMessages LOG = MessagesFactory.get( UrlRewriteMessages.class );
+
+ private Resolver resolver;
+ private UrlRewriter rewriter;
+ private UrlRewriter.Direction direction;
+
+ public XmlUrlRewriteFilterReader( Reader reader, UrlRewriter rewriter, Resolver resolver, UrlRewriter.Direction direction, UrlRewriteFilterContentDescriptor config )
+ throws IOException, ParserConfigurationException, XMLStreamException {
+ super( reader, config );
+ this.resolver = resolver;
+ this.rewriter = rewriter;
+ this.direction = direction;
+ }
+
+ //TODO: Need to limit which values are attempted to be filtered by the name.
+ private String filterValueString( String name, String value, String rule ) {
+ try {
+ Template input = Parser.parseLiteral( value );
+ if( input != null ) {
+ Template output = rewriter.rewrite( resolver, input, direction, rule );
+ if( output != null ) {
+ value = output.getPattern();
+ } else {
+ LOG.failedToFilterValue( value, rule );
+ }
+ } else {
+ LOG.failedToParseValueForUrlRewrite( value );
+ }
+ } catch( URISyntaxException e ) {
+ LOG.failedToParseValueForUrlRewrite( value );
+ }
+ return value;
+ }
+
+ @Override
+ protected String filterAttribute( QName elementName, QName attributeName, String attributeValue, String ruleName ) {
+ return filterValueString( attributeName.getLocalPart(), attributeValue, ruleName );
+ }
+
+ @Override
+ protected String filterText( QName elementName, String text, String ruleName ) {
+ return filterValueString( elementName.getLocalPart(), text, ruleName );
+ }
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/xml/XmlUrlRewriteRulesExporter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/xml/XmlUrlRewriteRulesExporter.java b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/xml/XmlUrlRewriteRulesExporter.java
new file mode 100644
index 0000000..00927b6
--- /dev/null
+++ b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/xml/XmlUrlRewriteRulesExporter.java
@@ -0,0 +1,200 @@
+/**
+ * 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.knox.gateway.filter.rewrite.impl.xml;
+
+import org.apache.commons.beanutils.BeanUtils;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterBufferDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterContentDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterGroupDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterPathDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterScopeDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFlowDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFunctionDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteRuleDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteRulesDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteStepDescriptor;
+import org.apache.knox.gateway.filter.rewrite.i18n.UrlRewriteMessages;
+import org.apache.knox.gateway.filter.rewrite.spi.UrlRewriteRulesExporter;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterApplyDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterDetectDescriptor;
+import org.apache.knox.gateway.i18n.messages.MessagesFactory;
+import org.apache.knox.gateway.util.XmlUtils;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.io.IOException;
+import java.io.Writer;
+import java.lang.reflect.InvocationTargetException;
+
+public class XmlUrlRewriteRulesExporter implements UrlRewriteRulesExporter, XmlRewriteRulesTags {
+
+ private static final UrlRewriteMessages LOG = MessagesFactory.get( UrlRewriteMessages.class );
+
+ @Override
+ public String getFormat() {
+ return "xml";
+ }
+
+ @Override
+ public void store( UrlRewriteRulesDescriptor descriptor, Writer writer ) throws IOException {
+ try {
+ Document document = XmlUtils.createDocument();
+
+ Element root = document.createElement( ROOT );
+ document.appendChild( root );
+
+ if( !descriptor.getFunctions().isEmpty() ) {
+ Element functionsElement = document.createElement( FUNCTIONS );
+ root.appendChild( functionsElement );
+ for( UrlRewriteFunctionDescriptor function : descriptor.getFunctions() ) {
+ Element functionElement = createElement( document, function.name(), function );
+ functionsElement.appendChild( functionElement );
+ }
+ }
+
+ if( !descriptor.getRules().isEmpty() ) {
+ for( UrlRewriteRuleDescriptor rule : descriptor.getRules() ) {
+ Element ruleElement = createRule( document, rule );
+ root.appendChild( ruleElement );
+ }
+ }
+
+ if( !descriptor.getFilters().isEmpty() ) {
+ for( UrlRewriteFilterDescriptor filter : descriptor.getFilters() ) {
+ Element filterElement = createFilter( document, filter );
+ root.appendChild( filterElement );
+ }
+ }
+
+ XmlUtils.writeXml( document, writer );
+
+ } catch( ParserConfigurationException e ) {
+ throw new IOException( e );
+ } catch( TransformerException e ) {
+ throw new IOException( e );
+ } catch( InvocationTargetException e ) {
+ LOG.failedToWriteRulesDescriptor( e );
+ } catch( NoSuchMethodException e ) {
+ LOG.failedToWriteRulesDescriptor( e );
+ } catch( IntrospectionException e ) {
+ LOG.failedToWriteRulesDescriptor( e );
+ } catch( IllegalAccessException e ) {
+ LOG.failedToWriteRulesDescriptor( e );
+ }
+ }
+
+ private Element createFilter( Document document, UrlRewriteFilterDescriptor parent )
+ throws IntrospectionException, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
+ Element parentElement = createElement( document, FILTER, parent );
+ for( UrlRewriteFilterContentDescriptor child: parent.getContents() ) {
+ Element childElement = createFilterContent( document, child );
+ parentElement.appendChild( childElement );
+ }
+ return parentElement;
+ }
+
+ private Element createFilterContent( Document document, UrlRewriteFilterContentDescriptor parent )
+ throws IntrospectionException, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
+ Element parentElement = createElement( document, CONTENT, parent );
+ for( UrlRewriteFilterPathDescriptor child: parent.getSelectors() ) {
+ Element childElement = createFilterSelector( document, child );
+ parentElement.appendChild( childElement );
+ }
+ return parentElement;
+ }
+
+ private Element createFilterSelector( Document document, UrlRewriteFilterPathDescriptor parent )
+ throws IntrospectionException, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
+ Element parentElement = createElement( document, toTagName( parent ), parent );
+ if( parent instanceof UrlRewriteFilterGroupDescriptor) {
+ for( UrlRewriteFilterPathDescriptor child: ((UrlRewriteFilterGroupDescriptor)parent).getSelectors() ) {
+ Element childElement = createFilterSelector( document, child );
+ parentElement.appendChild( childElement );
+ }
+ }
+ return parentElement;
+ }
+
+ private Element createRule( Document document, UrlRewriteRuleDescriptor rule )
+ throws IntrospectionException, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
+ Element ruleElement = createElement( document, RULE, rule );
+ for( UrlRewriteStepDescriptor step: rule.steps() ) {
+ Element childElement = createStep( document, step );
+ ruleElement.appendChild( childElement );
+ }
+ return ruleElement;
+ }
+
+ private Element createStep( Document document, UrlRewriteStepDescriptor step )
+ throws IntrospectionException, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
+ Element parentElement = createElement( document, step.type(), step );
+ if( step instanceof UrlRewriteFlowDescriptor) {
+ UrlRewriteFlowDescriptor flow = (UrlRewriteFlowDescriptor)step;
+ for( Object child: flow.steps() ) {
+ UrlRewriteStepDescriptor childStep = (UrlRewriteStepDescriptor)child;
+ Element childElement = createStep( document, childStep );
+ parentElement.appendChild( childElement );
+ }
+
+ }
+ return parentElement;
+ }
+
+ private Element createElement( Document document, String name, Object bean )
+ throws IntrospectionException, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
+ Element element = document.createElement( name );
+ BeanInfo beanInfo = Introspector.getBeanInfo( bean.getClass(), Object.class );
+ for( PropertyDescriptor propInfo: beanInfo.getPropertyDescriptors() ) {
+ String propName = propInfo.getName();
+ if( propInfo.getReadMethod() != null && String.class.isAssignableFrom( propInfo.getPropertyType() ) ) {
+ String propValue = BeanUtils.getProperty( bean, propName );
+ if( propValue != null && !propValue.isEmpty() ) {
+ // Doing it the hard way to avoid having the &'s in the query string escaped at &
+ Attr attr = document.createAttribute( propName );
+ attr.setValue( propValue );
+ element.setAttributeNode( attr );
+ //element.setAttribute( propName, propValue );
+ }
+ }
+ }
+ return element;
+ }
+
+ private static String toTagName( final UrlRewriteFilterPathDescriptor descriptor ) {
+ if( descriptor instanceof UrlRewriteFilterApplyDescriptor) {
+ return APPLY;
+ } else if( descriptor instanceof UrlRewriteFilterDetectDescriptor) {
+ return DETECT;
+ } else if( descriptor instanceof UrlRewriteFilterBufferDescriptor) {
+ return BUFFER;
+ } else if( descriptor instanceof UrlRewriteFilterScopeDescriptor) {
+ return SCOPE;
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/xml/XmlUrlRewriteRulesImporter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/xml/XmlUrlRewriteRulesImporter.java b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/xml/XmlUrlRewriteRulesImporter.java
new file mode 100644
index 0000000..ec60826
--- /dev/null
+++ b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/xml/XmlUrlRewriteRulesImporter.java
@@ -0,0 +1,52 @@
+/**
+ * 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.knox.gateway.filter.rewrite.impl.xml;
+
+import org.apache.commons.digester3.Digester;
+import org.apache.commons.digester3.ExtendedBaseRules;
+import org.apache.commons.digester3.binder.DigesterLoader;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteRulesDescriptor;
+import org.apache.knox.gateway.filter.rewrite.spi.UrlRewriteRulesImporter;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import static org.apache.commons.digester3.binder.DigesterLoader.newLoader;
+
+public class XmlUrlRewriteRulesImporter implements UrlRewriteRulesImporter {
+
+ private static DigesterLoader loader = newLoader( new XmlRewriteRulesDigester() );
+
+ @Override
+ public String getFormat() {
+ return "xml";
+ }
+
+ @Override
+ public UrlRewriteRulesDescriptor load( Reader reader ) throws IOException {
+ Digester digester = loader.newDigester( new ExtendedBaseRules() );
+ digester.setValidating( false );
+ try {
+ UrlRewriteRulesDescriptor rules = digester.parse( reader );
+ return rules;
+ } catch( SAXException e ) {
+ throw new IOException( e );
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/xml/XmlUrlRewriteStreamFilter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/xml/XmlUrlRewriteStreamFilter.java b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/xml/XmlUrlRewriteStreamFilter.java
new file mode 100644
index 0000000..d2aa47f
--- /dev/null
+++ b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/xml/XmlUrlRewriteStreamFilter.java
@@ -0,0 +1,67 @@
+/**
+ * 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.knox.gateway.filter.rewrite.impl.xml;
+
+import org.apache.commons.io.input.ReaderInputStream;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterContentDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriter;
+import org.apache.knox.gateway.filter.rewrite.spi.UrlRewriteStreamFilter;
+import org.apache.knox.gateway.util.urltemplate.Resolver;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.stream.XMLStreamException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class XmlUrlRewriteStreamFilter implements UrlRewriteStreamFilter {
+
+ private static String[] TYPES = new String[]{ "application/xml", "text/xml", "*/xml" };
+ private static String[] NAMES = new String[]{ null };
+
+ @Override
+ public String[] getTypes() {
+ return TYPES;
+ }
+
+ @Override
+ public String[] getNames() {
+ return NAMES;
+ }
+
+ @Override
+ public InputStream filter(
+ InputStream stream,
+ String encoding,
+ UrlRewriter rewriter,
+ Resolver resolver,
+ UrlRewriter.Direction direction,
+ UrlRewriteFilterContentDescriptor config )
+ throws IOException {
+ try {
+ return new ReaderInputStream(
+ new XmlUrlRewriteFilterReader(
+ new InputStreamReader( stream, encoding ), rewriter, resolver, direction, config ), encoding );
+ } catch( ParserConfigurationException e ) {
+ throw new IOException( e );
+ } catch( XMLStreamException e ) {
+ throw new IOException( e );
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteActionDescriptorBase.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteActionDescriptorBase.java b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteActionDescriptorBase.java
new file mode 100644
index 0000000..7451415
--- /dev/null
+++ b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteActionDescriptorBase.java
@@ -0,0 +1,83 @@
+/**
+ * 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.knox.gateway.filter.rewrite.spi;
+
+import org.apache.knox.gateway.filter.rewrite.ext.UrlRewriteActionDescriptor;
+
+public abstract class UrlRewriteActionDescriptorBase
+ extends UrlRewriteStepDescriptorBase<UrlRewriteActionDescriptor>
+ implements UrlRewriteActionDescriptor {
+
+ private String operation;
+ private String parameter;
+
+ protected UrlRewriteActionDescriptorBase( String type ) {
+ super( type );
+ }
+
+ @Override
+ public String operation() {
+ return operation;
+ }
+
+ @Override
+ public UrlRewriteActionDescriptor operation( String operation ) {
+ this.operation = operation;
+ return this;
+ }
+
+ public void setOperation( String operation ) {
+ operation( operation );
+ }
+
+ public void setOper( String operation ) {
+ operation( operation );
+ }
+
+ public void setOp( String operation ) {
+ operation( operation );
+ }
+
+ public String getOper() {
+ return operation();
+ }
+
+ @Override
+ public String parameter() {
+ return parameter;
+ }
+
+ @Override
+ public UrlRewriteActionDescriptor parameter( String parameter ) {
+ this.parameter = parameter;
+ return this;
+ }
+
+ public void setParameter( String parameter ) {
+ parameter( parameter );
+ }
+
+ public void setParam( String parameter ) {
+ parameter( parameter );
+ }
+
+ public String getParam() {
+ return parameter();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteContext.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteContext.java b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteContext.java
new file mode 100644
index 0000000..5aa82c1
--- /dev/null
+++ b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteContext.java
@@ -0,0 +1,45 @@
+/**
+ * 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.knox.gateway.filter.rewrite.spi;
+
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriter;
+import org.apache.knox.gateway.util.urltemplate.Evaluator;
+import org.apache.knox.gateway.util.urltemplate.Params;
+import org.apache.knox.gateway.util.urltemplate.Template;
+
+public interface UrlRewriteContext {
+
+ UrlRewriter.Direction getDirection();
+
+ Template getOriginalUrl();
+
+ Template getCurrentUrl();
+
+ void setCurrentUrl( Template url );
+
+ /**
+ * Adds parameters to the rewrite context and replaces some of them if they already exist
+ * @param parameters the parameters to be added or replaced
+ */
+ void addParameters( Params parameters );
+
+ Params getParameters();
+
+ Evaluator getEvaluator();
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteFlowDescriptorBase.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteFlowDescriptorBase.java b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteFlowDescriptorBase.java
new file mode 100644
index 0000000..fcfee24
--- /dev/null
+++ b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteFlowDescriptorBase.java
@@ -0,0 +1,115 @@
+/**
+ * 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.knox.gateway.filter.rewrite.spi;
+
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFlowDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteStepDescriptor;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteStepDescriptorFactory;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteStepFlow;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class UrlRewriteFlowDescriptorBase<T> extends UrlRewriteStepDescriptorBase<T> implements
+ UrlRewriteFlowDescriptor<T> {
+
+ private UrlRewriteStepFlow flow;
+ private List<UrlRewriteStepDescriptor> steps = new ArrayList<UrlRewriteStepDescriptor>();
+
+ public UrlRewriteFlowDescriptorBase( String type ) {
+ super( type );
+ }
+
+ @Override
+ public UrlRewriteStepFlow flow() {
+ return flow;
+ }
+
+ @SuppressWarnings( "unchecked" )
+ @Override
+ public <F extends UrlRewriteFlowDescriptor<?>> F flow( String flow ) {
+ setFlow( flow );
+ return (F)this;
+ }
+
+ @SuppressWarnings( "unchecked" )
+ @Override
+ public <F extends UrlRewriteFlowDescriptor<?>> F flow( UrlRewriteStepFlow flow ) {
+ setFlow( flow );
+ return (F)this;
+ }
+
+ public void setFlow( UrlRewriteStepFlow flow ) {
+ this.flow = flow;
+ }
+
+ public void setFlow( String flow ) {
+ flow = flow.trim().toUpperCase();
+ this.flow = Enum.valueOf( UrlRewriteStepFlow.class, flow );
+ }
+
+ public String getFlow() {
+ String str = null;
+ if( flow != null ) {
+ str = flow.toString();
+ }
+ return str;
+ }
+
+ @Override
+ public List<UrlRewriteStepDescriptor> steps() {
+ return steps;
+ }
+
+// @Override
+// public UrlRewriteMatchDescriptor addMatch() {
+// UrlRewriteMatchDescriptor step = new UrlRewriteMatchDescriptorExt();
+// steps.add( step );
+// return step;
+// }
+//
+// @Override
+// public UrlRewriteCheckDescriptor addCheck() {
+// UrlRewriteCheckDescriptor step = new UrlRewriteCheckDescriptorExt();
+// steps.add( step );
+// return step;
+// }
+//
+// @Override
+// public UrlRewriteControlDescriptor addControl() {
+// UrlRewriteControlDescriptor step = new UrlRewriteControlDescriptorExt();
+// steps.add( step );
+// return step;
+// }
+//
+// @Override
+// public UrlRewriteActionDescriptor addAction() {
+// UrlRewriteActionDescriptor step = new UrlRewriteActionDescriptorBase();
+// steps.add( step );
+// return step;
+// }
+
+ @SuppressWarnings( "unchecked" )
+ @Override
+ public <T extends UrlRewriteStepDescriptor<?>> T addStep( String type ) {
+ T step = (T)UrlRewriteStepDescriptorFactory.create( type );
+ steps.add( step );
+ return (T)step;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteFunctionProcessor.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteFunctionProcessor.java b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteFunctionProcessor.java
new file mode 100644
index 0000000..8028145
--- /dev/null
+++ b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteFunctionProcessor.java
@@ -0,0 +1,31 @@
+/**
+ * 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.knox.gateway.filter.rewrite.spi;
+
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteEnvironment;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFunctionDescriptor;
+
+public interface UrlRewriteFunctionProcessor<T extends UrlRewriteFunctionDescriptor> extends UrlRewriteResolver {
+
+ String name();
+
+ void initialize( UrlRewriteEnvironment environment, T descriptor ) throws Exception;
+
+ void destroy() throws Exception;
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteFunctionProcessorBase.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteFunctionProcessorBase.java b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteFunctionProcessorBase.java
new file mode 100644
index 0000000..7638f37
--- /dev/null
+++ b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteFunctionProcessorBase.java
@@ -0,0 +1,31 @@
+/**
+ * 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.knox.gateway.filter.rewrite.spi;
+
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteEnvironment;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFunctionDescriptor;
+
+public abstract class UrlRewriteFunctionProcessorBase<T extends UrlRewriteFunctionDescriptor> implements UrlRewriteFunctionProcessor<T> {
+
+ public void initialize( UrlRewriteEnvironment environment, T descriptor ) throws Exception {
+ }
+
+ public void destroy() throws Exception {
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteResolver.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteResolver.java b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteResolver.java
new file mode 100644
index 0000000..c190f55
--- /dev/null
+++ b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteResolver.java
@@ -0,0 +1,26 @@
+/**
+ * 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.knox.gateway.filter.rewrite.spi;
+
+import java.util.List;
+
+public interface UrlRewriteResolver {
+
+ List<String> resolve( UrlRewriteContext context, List<String> parameter ) throws Exception;
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteRulesExporter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteRulesExporter.java b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteRulesExporter.java
new file mode 100644
index 0000000..d2dd56e
--- /dev/null
+++ b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteRulesExporter.java
@@ -0,0 +1,31 @@
+/**
+ * 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.knox.gateway.filter.rewrite.spi;
+
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteRulesDescriptor;
+
+import java.io.IOException;
+import java.io.Writer;
+
+public interface UrlRewriteRulesExporter {
+
+ String getFormat();
+
+ void store( UrlRewriteRulesDescriptor rules, Writer writer ) throws IOException;
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteRulesImporter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteRulesImporter.java b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteRulesImporter.java
new file mode 100644
index 0000000..ae963bb
--- /dev/null
+++ b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteRulesImporter.java
@@ -0,0 +1,31 @@
+/**
+ * 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.knox.gateway.filter.rewrite.spi;
+
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteRulesDescriptor;
+
+import java.io.IOException;
+import java.io.Reader;
+
+public interface UrlRewriteRulesImporter {
+
+ String getFormat();
+
+ UrlRewriteRulesDescriptor load( Reader reader ) throws IOException;
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteStepDescriptorBase.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteStepDescriptorBase.java b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteStepDescriptorBase.java
new file mode 100644
index 0000000..b51d036
--- /dev/null
+++ b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteStepDescriptorBase.java
@@ -0,0 +1,46 @@
+/**
+ * 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.knox.gateway.filter.rewrite.spi;
+
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteStepDescriptor;
+
+public abstract class UrlRewriteStepDescriptorBase<T> implements UrlRewriteStepDescriptor<T> {
+
+ private String type;
+
+ public UrlRewriteStepDescriptorBase( String type ) {
+ this.type = type;
+ }
+
+ @Override
+ public String type() {
+ return type;
+ }
+
+ @Override
+ @SuppressWarnings( "unchecked" )
+ public T type( String type ) {
+ this.type = type;
+ return (T)this;
+ }
+
+ public void setType( String type ) {
+ this.type = type;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteStepProcessor.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteStepProcessor.java b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteStepProcessor.java
new file mode 100644
index 0000000..bc44db2
--- /dev/null
+++ b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteStepProcessor.java
@@ -0,0 +1,33 @@
+/**
+ * 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.knox.gateway.filter.rewrite.spi;
+
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteEnvironment;
+import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteStepDescriptor;
+
+public interface UrlRewriteStepProcessor<T extends UrlRewriteStepDescriptor> {
+
+ String getType();
+
+ void initialize( UrlRewriteEnvironment environment, T descriptor ) throws Exception;
+
+ UrlRewriteStepStatus process( UrlRewriteContext context ) throws Exception;
+
+ void destroy() throws Exception;
+
+}
http://git-wip-us.apache.org/repos/asf/knox/blob/af9b0c3d/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteStepStatus.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteStepStatus.java b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteStepStatus.java
new file mode 100644
index 0000000..67e8a36
--- /dev/null
+++ b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/spi/UrlRewriteStepStatus.java
@@ -0,0 +1,20 @@
+/**
+ * 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.knox.gateway.filter.rewrite.spi;
+
+public enum UrlRewriteStepStatus { SUCCESS, FAILURE, FINISHED }