001/*
002 * (C) Copyright 2006-2007 Nuxeo SAS <http://nuxeo.com> and others
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     Jean-Marc Orliaguet, Chalmers
011 *
012 * $Id$
013 */
014
015package org.nuxeo.theme.html.filters.standalone;
016
017import java.util.regex.Matcher;
018import java.util.regex.Pattern;
019
020import org.nuxeo.theme.rendering.RenderingInfo;
021import org.nuxeo.theme.rendering.StandaloneFilter;
022
023public final class XmlNamespaces extends StandaloneFilter {
024
025    static final Pattern tagsPattern = Pattern.compile("(.*?)<([^/@!<>].*?)>(.*)", Pattern.DOTALL);
026
027    static final String xmlnsAttrStr = "xmlns[^\"]+\"([^\"]+)\"";
028
029    static final String spaceXmlnsAttrStr = " " + xmlnsAttrStr;
030
031    static final Pattern xmlnsAttrPattern = Pattern.compile(xmlnsAttrStr, Pattern.DOTALL);
032
033    @Override
034    public RenderingInfo process(final RenderingInfo info, final boolean cache) {
035        String markup = info.getMarkup();
036
037        final Matcher attrMatcher = xmlnsAttrPattern.matcher(markup);
038        if (!attrMatcher.find()) {
039            return info;
040        }
041
042        final StringBuilder s = new StringBuilder();
043        do {
044            final String attr = attrMatcher.group(0);
045            if (s.indexOf(attr) < 0) {
046                s.append(' ');
047                s.append(attr);
048            }
049        } while (attrMatcher.find());
050
051        // remove existing uid attributes, if any
052        markup = markup.replaceAll(spaceXmlnsAttrStr, "");
053
054        final Matcher firstMatcher = tagsPattern.matcher(markup);
055        if (!firstMatcher.find()) {
056            return info;
057        }
058
059        // write the final markup
060        final String f = String.format("%s<%s%s>%s", firstMatcher.group(1), firstMatcher.group(2), s.toString(),
061                firstMatcher.group(3));
062
063        info.setMarkup(f);
064        return info;
065    }
066
067}