001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.wicket.markup.transformer;
018
019import org.apache.wicket.Component;
020import org.apache.wicket.Page;
021import org.apache.wicket.WicketRuntimeException;
022import org.apache.wicket.markup.ComponentTag;
023import org.apache.wicket.markup.MarkupResourceStream;
024
025/**
026 * An IBehavior which can be added to any component except ListView. It allows to post-process
027 * (XSLT) the markup generated by the component. The *.xsl resource must be located in the same path
028 * as the nearest parent with an associated markup and must have a filename equal to the component's
029 * id.
030 * <p>
031 * The containers tag will be the root element of the xml data applied for transformation to ensure
032 * the xml data are well formed (single root element). In addition the attribute
033 * <code>xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd</code> is added
034 * to the root element to allow the XSL processor to handle the wicket namespace.
035 * <p>
036 * The reason why the transformer can not be used to XSLT the ListViews output is because of the
037 * ListViews markup being reused for each ListItem. Please use a XsltOutputTransformerContainer
038 * instead. Note: if the ListView is used to print a list of &lt;tr&gt; tags, than the transformer
039 * container must enclose the &lt;table&gt; tag as well to be HTML compliant.
040 * 
041 * @see org.apache.wicket.markup.transformer.AbstractOutputTransformerContainer
042 * @see org.apache.wicket.markup.transformer.XsltOutputTransformerContainer
043 * 
044 * @author Juergen Donnerstag
045 */
046public class XsltTransformerBehavior extends AbstractTransformerBehavior
047{
048        private static final long serialVersionUID = 1L;
049
050        /** An optional xsl file path */
051        private final String xslFile;
052
053        /**
054         * Construct.
055         */
056        public XsltTransformerBehavior()
057        {
058                xslFile = null;
059        }
060
061        /**
062         * @param xslFilePath
063         * @see XsltTransformer#XsltTransformer(String)
064         */
065        public XsltTransformerBehavior(final String xslFilePath)
066        {
067                xslFile = xslFilePath;
068        }
069
070        @Override
071        public void onComponentTag(final Component component, final ComponentTag tag)
072        {
073                // Make the XSLT processor happy and allow it to handle the wicket tags
074                // and attributes that are in the wicket namespace
075                tag.put("xmlns:wicket", MarkupResourceStream.WICKET_XHTML_DTD);
076
077                super.onComponentTag(component, tag);
078        }
079
080        @Override
081        public CharSequence transform(final Component component, final CharSequence output)
082                throws Exception
083        {
084                return new XsltTransformer(xslFile).transform(component, output);
085        }
086
087        @Override
088        public void bind(final Component component)
089        {
090                if (component instanceof Page)
091                {
092                        throw new WicketRuntimeException(
093                                "You can not attach a XstlTransformerBehavior to a Page. It can be attached to any other component.");
094                }
095                super.bind(component);
096        }
097}