/** * 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.hadoop.gateway.filter.rewrite.impl.xml; import org.apache.commons.beanutils.BeanUtils; import org.apache.hadoop.gateway.filter.rewrite.api.*; import org.apache.hadoop.gateway.filter.rewrite.i18n.UrlRewriteMessages; import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteRulesExporter; import org.apache.hadoop.gateway.i18n.messages.MessagesFactory; import org.apache.hadoop.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(); } } }