You are viewing a plain text version of this content. The canonical link for it is here.
Posted to portalapps-dev@portals.apache.org by wo...@apache.org on 2014/08/18 00:58:19 UTC

svn commit: r1618527 [2/3] - in /portals/applications/webcontent/trunk: ./ portlets/ portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/ portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/ portle...

Added: portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/RewriterController.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/RewriterController.java?rev=1618527&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/RewriterController.java (added)
+++ portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/RewriterController.java Sun Aug 17 22:58:18 2014
@@ -0,0 +1,93 @@
+/*
+ * 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.portals.applications.webcontent2.portlet.rewriter;
+
+import java.io.InputStream;
+import java.io.Reader;
+
+import org.apache.portals.applications.webcontent2.portlet.rewriter.rules.Ruleset;
+
+/**
+ * RewriterService
+ *
+ * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
+ * @version $Id: RewriterController.java 816126 2009-09-17 10:22:06Z woonsan $
+ */
+public interface RewriterController 
+{
+    public String SERVICE_NAME = "rewriter";
+
+    /**
+     * Creates a basic rewriter that does not support rulesets configurations.
+     * The Rewriter implementation is configured in the service configuration.
+     *  
+     * @return A new rewriter that does not support rulesets.
+     * @throws InstantiationException
+     * @throws 
+     * @throws IllegalAccessException
+     */
+    Rewriter createRewriter()
+        throws IllegalAccessException, InstantiationException;
+
+    /**
+     * Creates a rewriter that supports rulesets configurations.
+     * The rewriter uses the rulesets configuration to control rewriting.
+     * The Rewriter implementation is configured in the service configuration.
+     * 
+     * @param ruleset The ruleset configuration to control the rewriter.
+     * @return A new rewriter that supports rulesets.
+     */
+    RulesetRewriter createRewriter(Ruleset ruleset)
+        throws RewriterException;
+    
+
+    /**
+     * Creates a Parser Adaptor for the given mime type
+     * The Parser Adaptor implementation is configured in the service configuration.
+     * Only MimeTypes of "text/html" and "text/xml" are currently supported.
+     * 
+     * @param mimeType The mimetype to create a parser adaptor for.
+     * @return A new parser adaptor
+     */
+    ParserAdaptor createParserAdaptor(String mimeType)
+        throws RewriterException;
+    
+    /**
+     * Loads a XML-based Rewriter Ruleset given a reader to the XML configuration.
+     * 
+     * @param reader The stream to the XML configuration.
+     * @return A Ruleset configuration tree.
+     */
+    Ruleset loadRuleset(Reader reader);
+       
+    /**
+     * Lookup a Ruleset given a ruleset identifier.
+     * 
+     * @param id The identifier for the Ruleset.
+     * @return A Ruleset configuration tree.
+     */
+    Ruleset lookupRuleset(String id);
+    
+    /**
+     * Loads a XML-based Rewriter Ruleset given a stream to the XML configuration.
+     * 
+     * @param reader The stream to the XML configuration.
+     * @return A Ruleset configuration tree.
+     */
+    Ruleset loadRuleset(InputStream input);
+       
+}

Added: portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/RewriterException.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/RewriterException.java?rev=1618527&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/RewriterException.java (added)
+++ portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/RewriterException.java Sun Aug 17 22:58:18 2014
@@ -0,0 +1,71 @@
+/*
+ * 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.portals.applications.webcontent2.portlet.rewriter;
+
+/**
+ * RewriterException
+ *
+ * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
+ * @version $Id: RewriterException.java 764612 2009-04-13 21:17:59Z taylor $
+ */
+public class RewriterException extends Exception
+{
+    /**
+     * Constructs a new <code>RewriterException</code> without specified detail
+     * message.
+     */
+    public RewriterException()
+    {
+    }
+
+    /**
+     * Constructs a new <code>RewriterException</code> with specified detail
+     * message.
+     *
+     * @param msg the error message.
+     */
+    public RewriterException(String msg)
+    {
+        super(msg);
+    }
+
+    /**
+     * Constructs a new <code>RewriterException</code> with specified nested
+     * <code>Throwable</code>.
+     *
+     * @param nested the exception or error that caused this exception
+     *               to be thrown.
+     */
+    public RewriterException(Throwable nested)
+    {
+        super(nested);
+    }
+
+    /**
+     * Constructs a new <code>RewriterException</code> with specified detail
+     * message and nested <code>Throwable</code>.
+     *
+     * @param msg the error message.
+     * @param nested the exception or error that caused this exception
+     *               to be thrown.
+     */
+    public RewriterException(String msg, Throwable nested)
+    {
+        super(msg, nested);
+    }
+    
+}

Added: portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/RulesetRewriter.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/RulesetRewriter.java?rev=1618527&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/RulesetRewriter.java (added)
+++ portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/RulesetRewriter.java Sun Aug 17 22:58:18 2014
@@ -0,0 +1,42 @@
+/*
+ * 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.portals.applications.webcontent2.portlet.rewriter;
+
+import org.apache.portals.applications.webcontent2.portlet.rewriter.rules.Ruleset;
+
+/**
+ * RulesetRewriter
+ *
+ * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
+ * @version $Id: RulesetRewriter.java 764612 2009-04-13 21:17:59Z taylor $
+ */
+public interface RulesetRewriter extends Rewriter
+{
+    /**
+     * Set the Ruleset configuration for this rewriter.
+     * 
+     * @param ruleset The Ruleset configuration.
+     */
+    void setRuleset(Ruleset ruleset);
+
+    /**
+     * Get the Ruleset configuration for this rewriter.
+     * 
+     * @return The Ruleset configuration.
+     */    
+    Ruleset getRuleset();
+}

Added: portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/RulesetRewriterImpl.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/RulesetRewriterImpl.java?rev=1618527&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/RulesetRewriterImpl.java (added)
+++ portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/RulesetRewriterImpl.java Sun Aug 17 22:58:18 2014
@@ -0,0 +1,164 @@
+/*
+ * 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.portals.applications.webcontent2.portlet.rewriter;
+
+import java.util.Iterator;
+
+import org.apache.portals.applications.webcontent2.portlet.rewriter.rules.Attribute;
+import org.apache.portals.applications.webcontent2.portlet.rewriter.rules.Rule;
+import org.apache.portals.applications.webcontent2.portlet.rewriter.rules.Ruleset;
+import org.apache.portals.applications.webcontent2.portlet.rewriter.rules.Tag;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * RuleBasedRewriter
+ *
+ * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
+ * @version $Id: RulesetRewriterImpl.java 891414 2009-12-16 20:19:02Z rwatler $
+ */
+public class RulesetRewriterImpl extends BasicRewriter implements RulesetRewriter
+{
+    protected final static Logger log = LoggerFactory.getLogger(RulesetRewriterImpl.class);
+    
+    private Ruleset ruleset = null;
+    private boolean removeComments = false;
+
+    public boolean shouldStripTag(String tagid)
+    {        
+        if (null == ruleset)
+        {
+            return false;
+        }
+        
+        Tag tag = ruleset.getTag(tagid.toUpperCase());
+        if (null == tag)
+        {
+            return false;
+        }
+        return tag.getStrip();        
+    }
+            
+    public boolean shouldRemoveTag(String tagid)
+    {        
+        if (null == ruleset)
+        {
+            return false;
+        }
+        
+        Tag tag = ruleset.getTag(tagid.toUpperCase());
+        if (null == tag)
+        {
+            return false;
+        }
+        return tag.getRemove();
+    }
+
+    public void setRuleset(Ruleset ruleset)
+    {
+        this.ruleset = ruleset;
+    }
+    
+    public Ruleset getRuleset()
+    {
+        return this.ruleset;
+    }
+
+    public boolean shouldRemoveComments()
+    {
+        if (null == ruleset)
+        {
+            return false;
+        }
+        
+        return ruleset.getRemoveComments();                
+    }
+
+    public void enterConvertTagEvent(String tagid, MutableAttributes attributes)
+    {
+        if (null == ruleset)
+        {
+            return;
+        }
+        
+         Tag tag = ruleset.getTag(tagid.toUpperCase());
+        if (null == tag)
+        {
+             return;
+        }
+
+        Iterator attribRules = tag.getAttributes().iterator();
+        while (attribRules.hasNext())
+        {
+            Attribute attribute = (Attribute)attribRules.next();
+            String name = attribute.getId();
+            String value = attributes.getValue(name);
+ 
+            if (value != null) // && name.equalsIgnoreCase(attribute.getId()))
+            {
+                Rule rule = attribute.getRule();
+                if (null == rule)
+                {
+                    continue;
+                }
+                
+                if (!rule.shouldRewrite(value))
+                {
+                    continue;
+                }                                        
+                
+                String rewritten = rewriteUrl(value, tag.getId(), name, attributes);
+                if (null != rewritten) // return null indicates "don't rewrite" 
+                {
+                    if (rule.getSuffix() != null)
+                    {
+                        rewritten = rewritten.concat(rule.getSuffix());
+                    }
+                    
+                    attributes.addAttribute(name, rewritten);
+                                        
+                    if (rule.getPopup())
+                    {
+                        attributes.addAttribute("TARGET", "_BLANK");                        
+                    }
+                }
+            }            
+        }
+    }
+    
+    /**
+     * rewriteURL
+     * 
+     * @param url
+     * @param tag
+     * @param attribute
+     * @param otherAttributes
+     * @return the modified url which is a portlet action
+     * 
+     * Rewrites all urls HREFS with a portlet action
+     */
+    public String rewriteUrl(String url, String tag, String attribute, MutableAttributes otherAttributes)
+    {
+        return getBaseRelativeUrl(url);
+    }
+
+    public String enterConvertTextEvent(String tagid, String text)
+    {
+        return rewriteText(tagid, text);
+    }
+}

Added: portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/TicketParamRewriter.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/TicketParamRewriter.java?rev=1618527&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/TicketParamRewriter.java (added)
+++ portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/TicketParamRewriter.java Sun Aug 17 22:58:18 2014
@@ -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.portals.applications.webcontent2.portlet.rewriter;
+
+
+/**
+ * Parses looking for a Ticket Param, used in SSO portlets where ticket processing is required
+ * Often tickets are added as form parameters and checked on the authentication for better security
+ *
+ * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
+ * @version $Id: TicketParamRewriter.java 764612 2009-04-13 21:17:59Z taylor $
+ */
+public class TicketParamRewriter extends BasicRewriter
+{    
+    private String ticket;
+    private String ticketName;
+
+    public String getTicketName() 
+    {
+        return ticketName;
+    }
+
+    public void setTicketName(String ticketName) 
+    {
+        this.ticketName = ticketName;
+    }
+    
+    public String getTicket() 
+    {
+		return ticket;
+	}
+
+	public void setTicket(String ticket) 
+    {
+		this.ticket = ticket;
+	}
+    
+    public boolean enterSimpleTagEvent(String tag, MutableAttributes attrs)
+    {
+        if (tag.equalsIgnoreCase("input"))
+        {
+            String name = attrs.getValue("name");
+            String value = attrs.getValue("value");
+            if (name.equals(this.ticketName))
+            {
+            
+            	//System.out.println("*** TICKET attr=" + name + " val = " + value);    
+            	setTicket(value);
+            }
+        }        
+        return true;
+    }            
+}

Added: portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/WebContentRewriter.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/WebContentRewriter.java?rev=1618527&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/WebContentRewriter.java (added)
+++ portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/WebContentRewriter.java Sun Aug 17 22:58:18 2014
@@ -0,0 +1,158 @@
+/* 
+ * 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.portals.applications.webcontent2.portlet.rewriter;
+
+import java.util.StringTokenizer;
+
+import javax.portlet.PortletURL;
+
+/**
+ * WebContentRewriter
+ * 
+ * @author <a href="mailto:rogerrutr@apache.org">Roger Ruttimann </a>
+ * @version $Id: WebContentRewriter.java 764612 2009-04-13 21:17:59Z taylor $
+ */
+public class WebContentRewriter extends RulesetRewriterImpl implements Rewriter
+{
+    public void enterConvertTagEvent(String tagid, MutableAttributes attributes) 
+    {
+        super.enterConvertTagEvent(tagid, attributes);
+    }
+
+    /** parameters that need to be propagated in the action URL (since HTTP request parameters will not be available) */
+    public static final String ACTION_PARAMETER_URL    = "_AP_URL";
+    public static final String ACTION_PARAMETER_METHOD = "_AP_METHOD";
+
+    /*
+     * Portlet URL will be used to replace all URL's
+     */
+    private PortletURL actionURL = null;
+
+    /**
+     * Setters/getters for members
+     */
+    public void setActionURL(PortletURL action)
+    {
+        this.actionURL = action;
+    }
+
+    public PortletURL getActionURL()
+    {
+        return this.actionURL;
+    }
+
+    /**
+     * rewriteURL
+     * 
+     * @param url
+     * @param tag
+     * @param attribute
+     * @param otherAttributes
+     * @return the modified url which is a portlet action
+     * 
+     * Rewrites all urls HREFS with a portlet action
+     */
+    public String rewriteUrl(String url, String tag, String attribute, MutableAttributes otherAttributes)
+    {
+         String modifiedURL = url;
+        modifiedURL = getModifiedURL(url);
+
+        // translate "submit" URL's as actions
+        //  <A href="..."/>
+        //  <FORM submit="..."/>
+        if (( tag.equalsIgnoreCase("A") && attribute.equalsIgnoreCase("href")) ||
+            ( tag.equalsIgnoreCase("FORM") && attribute.equalsIgnoreCase("action")))
+                
+        {
+                // Regular URL just add a portlet action
+                if (this.actionURL != null)
+                {
+                    // create Action URL
+                    actionURL.setParameter(ACTION_PARAMETER_URL, modifiedURL);
+                    if (tag.equalsIgnoreCase("FORM"))
+                    {
+                        String httpMethod = otherAttributes.getValue("method");
+                        if (httpMethod != null)
+                            actionURL.setParameter(ACTION_PARAMETER_METHOD, httpMethod);
+                    }
+                    modifiedURL = actionURL.toString();
+                }
+        }
+
+        // Deal with links in an "onclick".
+        if (attribute.equalsIgnoreCase("onclick"))
+        {
+            // Check for onclick with location change
+            for (int i=0; i < otherAttributes.getLength(); i++) {
+
+                String name = otherAttributes.getQName(i);
+
+                if (name.equalsIgnoreCase("onclick")) {
+
+                    String value = otherAttributes.getValue(i);
+
+                    int index = value.indexOf(".location=");
+                    if (index >= 0) {
+                        String oldLocation = value.substring(index + ".location=".length());
+                        StringTokenizer tokenizer = new StringTokenizer(oldLocation, "\'\"");
+                        oldLocation = tokenizer.nextToken();
+
+                        modifiedURL = oldLocation;
+                        url = oldLocation;
+                        modifiedURL = getModifiedURL(url);
+
+                        // Regular URL just add a portlet action
+                        if (this.actionURL != null)
+                        {
+                            // create Action URL
+                            actionURL.setParameter(ACTION_PARAMETER_URL, modifiedURL);
+                            modifiedURL = actionURL.toString();
+                        }
+
+
+                        modifiedURL = value.replaceAll(oldLocation, modifiedURL);
+                    }
+                }
+            }
+
+
+        }
+        
+        // if ( !url.equalsIgnoreCase( modifiedURL ))
+        //     System.out.println("WebContentRewriter.rewriteUrl() - In tag: "+tag+", for attribute: "+attribute+", converted url: "+url+", to: "+modifiedURL+", base URL was: "+getBaseUrl());
+
+        return modifiedURL;
+    }
+
+    private String getModifiedURL(String url) {
+        String modifiedURL = url;
+        // Any relative URL needs to be converted to a full URL
+        if (url.startsWith("/") || (!url.startsWith("http:") && !url.startsWith("https:")))
+        {
+            if (this.getBaseUrl() != null)
+            {
+                modifiedURL = getBaseRelativeUrl(url) ;
+                // System.out.println("WebContentRewriter.rewriteUrl() - translated URL relative to base URL - result is: "+modifiedURL);
+  	        }
+            else
+            {
+                modifiedURL = url; // leave as is
+	        }
+        }
+        return modifiedURL;
+    }
+}

Added: portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/html/SwingAttributes.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/html/SwingAttributes.java?rev=1618527&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/html/SwingAttributes.java (added)
+++ portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/html/SwingAttributes.java Sun Aug 17 22:58:18 2014
@@ -0,0 +1,179 @@
+/*
+ * 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.portals.applications.webcontent2.portlet.rewriter.html;
+
+import java.util.Enumeration;
+
+import javax.swing.text.MutableAttributeSet;
+import javax.swing.text.html.HTML;
+import javax.swing.text.html.HTML.Attribute;
+
+import org.apache.portals.applications.webcontent2.portlet.rewriter.MutableAttributes;
+
+
+/**
+ * SwingAttributes
+ *
+ * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
+ * @version $Id: SwingAttributes.java 764612 2009-04-13 21:17:59Z taylor $
+ */
+public class SwingAttributes implements MutableAttributes
+{
+    MutableAttributeSet swingset;
+    
+    public SwingAttributes(MutableAttributeSet swingset)
+    {
+        this.swingset = swingset;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.xml.sax.Attributes#getLength()
+     */
+    public int getLength()
+    {
+        return swingset.getAttributeCount();
+    }
+    
+    /* (non-Javadoc)
+     * @see org.xml.sax.Attributes#getURI(int)
+     */
+    public String getURI(int index)
+    {
+        return "";
+    }
+    
+    /* (non-Javadoc)
+     * @see org.xml.sax.Attributes#getLocalName(int)
+     */
+    public String getLocalName(int index)
+    {
+        Enumeration e = swingset.getAttributeNames();
+        int ix = 0;
+        while (e.hasMoreElements())
+        {
+            Object object = e.nextElement();
+            if (ix == index)
+            {
+                return object.toString();
+            }
+        }
+        return null;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.xml.sax.Attributes#getQName(int)
+     */
+    public String getQName(int index)
+    {
+        return getLocalName(index);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.xml.sax.Attributes#getType(int)
+     */
+    public String getType(int index)
+    {
+        return "CDATA";
+    }
+    
+    /* (non-Javadoc)
+     * @see org.xml.sax.Attributes#getValue(int)
+     */
+    public String getValue(int index)
+    {
+        Enumeration e = swingset.getAttributeNames();
+        int ix = 0;
+        while (e.hasMoreElements())
+        {
+            Object object = e.nextElement();
+            if (ix == index)
+            {
+                return (String)swingset.getAttribute(object);
+            }
+        }
+        return null;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.xml.sax.Attributes#getIndex(java.lang.String, java.lang.String)
+     */
+    public int getIndex(String uri, String localPart)
+    {
+        return getIndex(localPart);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.xml.sax.Attributes#getIndex(java.lang.String)
+     */
+    public int getIndex(String qName)
+    {
+        Enumeration e = swingset.getAttributeNames();
+        int ix = 0;
+        while (e.hasMoreElements())
+        {
+            String name = (String)e.nextElement();
+            if (name.equalsIgnoreCase(qName))
+            {
+                return ix;
+            }
+        }
+        return -1;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.xml.sax.Attributes#getType(java.lang.String, java.lang.String)
+     */
+    public String getType(String uri, String localName)
+    {
+        return "CDATA";
+    }
+    
+    /* (non-Javadoc)
+     * @see org.xml.sax.Attributes#getType(java.lang.String)
+     */
+    public String getType(String qName)
+    {
+        return "CDATA";
+    }
+    
+    /* (non-Javadoc)
+     * @see org.xml.sax.Attributes#getValue(java.lang.String, java.lang.String)
+     */
+    public String getValue(String uri, String localName)
+    {
+        return getValue(localName);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.xml.sax.Attributes#getValue(java.lang.String)
+     */
+    public String getValue(String qName)
+    {
+        Attribute att = HTML.getAttributeKey(qName.toLowerCase());        
+        return (String)swingset.getAttribute(att);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.portals.applications.webcontent.cps.rewriter.MutableAttributes#addAttribute(java.lang.String, java.lang.Object)
+     */
+    public void addAttribute(String name, Object value)
+    {
+        Attribute att = HTML.getAttributeKey(name.toLowerCase());
+        swingset.addAttribute(att, value);
+    }
+
+}

Added: portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/html/SwingParserAdaptor.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/html/SwingParserAdaptor.java?rev=1618527&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/html/SwingParserAdaptor.java (added)
+++ portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/html/SwingParserAdaptor.java Sun Aug 17 22:58:18 2014
@@ -0,0 +1,573 @@
+/*
+ * 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.portals.applications.webcontent2.portlet.rewriter.html;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.Enumeration;
+import java.util.Stack;
+
+import javax.swing.text.MutableAttributeSet;
+import javax.swing.text.html.HTML;
+import javax.swing.text.html.HTMLEditorKit;
+
+import org.apache.portals.applications.webcontent2.portlet.rewriter.ParserAdaptor;
+import org.apache.portals.applications.webcontent2.portlet.rewriter.Rewriter;
+import org.apache.portals.applications.webcontent2.portlet.rewriter.RewriterException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * HTML Parser Adaptor for the Swing 'HotJava' parser.
+ *
+ * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
+ * @version $Id: SwingParserAdaptor.java 891414 2009-12-16 20:19:02Z rwatler $
+ */
+public class SwingParserAdaptor implements ParserAdaptor
+{
+    protected final static Logger log = LoggerFactory.getLogger(SwingParserAdaptor.class);
+
+    private SwingParserAdaptor.Callback callback = null;
+    private String lineSeparator;
+    private boolean skippingImplied = false;
+    private Rewriter rewriter;
+    
+    /*
+     * Construct a swing (hot java) parser adaptor
+     * Receives a Rewriter parameter, which is used as a callback when rewriting URLs.
+     * The rewriter object executes the implementation specific URL rewriting.
+     *
+     * @param rewriter The rewriter object that is called back during URL rewriting
+     */
+    public SwingParserAdaptor()
+    {
+        lineSeparator = System.getProperty("line.separator", "\r\n");         
+    }
+
+    /*
+     * Parses and an HTML document, rewriting all URLs as determined by the Rewriter callback
+     *
+     *
+     * @param reader The input stream reader 
+     *
+     * @throws MalformedURLException 
+     *
+     * @return An HTML-String with rewritten URLs.
+     */    
+    public void rewrite(Rewriter rewriter, Reader reader, Writer writer)
+        throws RewriterException
+    {
+        try
+        {
+            this.rewriter = rewriter;            
+            HTMLEditorKit.Parser parser = new SwingParserAdaptor.ParserGetter().getParser();                    
+            callback = new SwingParserAdaptor.Callback(writer);
+            parser.parse(reader, callback, true);
+        } 
+        catch (Exception e)
+        {
+            e.printStackTrace();
+            throw new RewriterException(e);
+        }
+    }
+
+    public void parse(Rewriter rewriter, Reader reader)
+        throws RewriterException    
+    {
+        try
+        {
+            this.rewriter = rewriter;            
+            HTMLEditorKit.Parser parser = new SwingParserAdaptor.ParserGetter().getParser();        
+            callback = new SwingParserAdaptor.Callback(null);
+            parser.parse(reader, callback, true);
+        } 
+        catch (Exception e)
+        {
+            e.printStackTrace();
+            throw new RewriterException(e);
+        }
+    }
+    
+    /*
+     * This Class is needed, because getParser is protected and therefore 
+     *  only accessibly by a subclass
+     */
+    class ParserGetter extends HTMLEditorKit
+    {
+
+        public HTMLEditorKit.Parser getParser()
+        {
+            return super.getParser();
+        }
+    } 
+    
+    /*
+     *  Swing Parser Callback from the HTMLEditorKit.
+     * This class handles all SAX-like events during parsing.
+     *
+     */
+    class Callback extends HTMLEditorKit.ParserCallback
+    {
+        // either handling of <FORM> is buggy, or I made some weird mistake ... 
+        // ... JDK 1.3 sends double "</form>"-tags on closing <form>
+        private boolean inForm = false; 
+        private boolean inScript = false; 
+        private boolean strip = false;
+        private boolean simpleTag = false;
+        private String stripTag = null;
+        private Writer writer = null;
+        private Stack tagStack = new Stack();
+
+        private Callback (Writer writer) 
+        {
+            this.writer = writer;
+        }
+
+        //
+        // -------------- Hot Java event callbacks... --------------------
+        //
+
+        /*
+         *  Hot Java event callback for text (all data in between tags)
+         * 
+         * @param values The array of characters containing the text.
+         */
+        public void handleText(char[] values,int param) 
+        {
+             if (strip)
+             {                               
+                 return;
+             }                                      
+             if (values[0] == '>')
+             {                            
+                 return;
+             }     
+             if (false == rewriter.enterText(values, param))
+             {
+                return;
+             }                    
+
+             if (!tagStack.isEmpty())
+             {
+                 String tag = (String)tagStack.peek();
+                 String convertedValues = convertText(tag, new String(values));
+                 if (convertedValues != null)
+                 {
+                     values = convertedValues.toCharArray();
+                 }
+             }
+
+            addToResult(values);
+        }
+
+        private void write(String text)
+            throws IOException
+        {
+            if (writer != null)
+            {
+                writer.write(text);
+            }
+        }
+        
+        /*
+         * Hot Java event callback for handling a simple tag (without begin/end)
+         *
+         * @param tag The HTML tag being handled.
+         * @param attrs The mutable HTML attribute set for the current HTML element.         
+         * @param position the position of the tag.         
+         *
+         */
+        public void handleSimpleTag(HTML.Tag htmlTag, MutableAttributeSet attrs, int param) 
+        {
+            String tag = htmlTag.toString();
+            
+            if (false == rewriter.enterSimpleTagEvent(tag, new SwingAttributes(attrs)))
+            {
+                return;
+            }
+
+            if (strip)
+            {
+                return;
+            }
+            
+            if (rewriter.shouldStripTag(tag))
+            {
+                return;            
+            }
+            
+            if (rewriter.shouldRemoveTag(tag))
+            {
+                return;
+            }
+            
+            try
+            {
+                simpleTag = true;                
+                appendTagToResult(htmlTag, attrs);
+                write(lineSeparator);
+/*
+                if (tag.toString().equalsIgnoreCase("param") ||
+                    tag.toString().equalsIgnoreCase("object") ||
+                    tag.toString().equalsIgnoreCase("embed"))
+                {
+                    write(lineSeparator);
+                }
+*/                
+                simpleTag = false;
+                String appended = rewriter.exitSimpleTagEvent(tag, new SwingAttributes(attrs));
+                if (null != appended)
+                {
+                    write(appended);
+                }
+            }
+            catch (Exception e)
+            {
+                log.error("Simple tag parsing error", e);                    
+            }
+        }
+
+        /*
+         * Hot Java event callback for handling a start tag.
+         *
+         * @param tag The HTML tag being handled.
+         * @param attrs The mutable HTML attribute set for the current HTML element.         
+         * @param position the position of the tag.         
+         *
+         */
+        public void handleStartTag(HTML.Tag htmlTag,  MutableAttributeSet attrs, int position) 
+        {
+            String tag = htmlTag.toString();
+            tagStack.push(tag);
+            
+            if (false == rewriter.enterStartTagEvent(tag, new SwingAttributes(attrs)))
+            {
+                return;
+            }
+            
+            if (strip)
+            {
+                return;
+            }
+            
+            if (rewriter.shouldStripTag(tag))
+            {
+                stripTag = tag;
+                strip = true;
+                return;            
+            }
+            
+            if (rewriter.shouldRemoveTag(tag))
+            {
+                return;
+            }
+            
+            try
+            {
+                appendTagToResult(htmlTag, attrs);
+                formatLine(htmlTag);
+                String appended = rewriter.exitStartTagEvent(tag, new SwingAttributes(attrs));
+                if (null != appended)
+                {
+                    write(appended);
+                }
+            }                    
+            catch (Exception e)
+            {
+                log.error("Start tag parsing error", e);                    
+            }
+                    
+        }
+        
+
+
+        /*
+         * Hot Java event callback for handling an end tag.
+         *
+         * @param tag The HTML tag being handled.
+         * @param position the position of the tag.
+         *
+         */
+        public void handleEndTag(HTML.Tag htmlTag, int position) 
+        {
+            String tag = htmlTag.toString();
+            if (!tagStack.isEmpty() && tag.equals(tagStack.peek()))
+            {
+                tagStack.pop();
+            }
+            if (false == rewriter.enterEndTagEvent(tag.toString()))
+            {
+                return;
+            }
+            
+            if (strip)
+            {
+                if (tag.equalsIgnoreCase(stripTag))
+                {
+                    strip = false;
+                    stripTag = null;
+                }
+                return;
+            }
+            
+            if (rewriter.shouldRemoveTag(tag))
+            {
+                return;                                
+            }
+             
+            try
+            {                            
+                addToResult("</").addToResult(tag).addToResult(">");
+    
+                // formatLine(htmlTag);
+                write(lineSeparator);
+                
+                String appended = rewriter.exitEndTagEvent(tag);
+                if (null != appended)
+                {
+                    write(appended);
+                }
+            }                    
+            catch (Exception e)
+            {
+                log.error("End tag parsing error", e);                                    
+            }                    
+        }
+
+
+        /*
+         * Hot Java event callback for handling errors.
+         *
+         * @param str The error message from Swing.
+         * @param param A parameter passed to handler.
+         *
+         */
+        public void handleError(java.lang.String str,int param) 
+        {
+            // System.out.println("Handling error: " + str);
+        }
+
+        /*
+         * Hot Java event callback for HTML comments.
+         *
+         * @param values The character array of text comments.
+         * @param param A parameter passed to handler.
+         *
+         */
+        public void handleComment(char[] values,int param) 
+        {
+            if (strip || rewriter.shouldRemoveComments())
+            {
+                return;             
+            }
+            addToResult("<!-- ").addToResult(values).addToResult(" -->").addToResult(lineSeparator);
+        }
+
+        /*
+         * Hot Java event callback for end of line strings.
+         *
+         * @param str The end-of-line string.
+         *
+         */
+        public void handleEndOfLineString(java.lang.String str) 
+        {
+            if (strip)
+            {                               
+                return;
+            }                                      
+            
+            addToResult(lineSeparator);
+            addToResult(str);
+        }
+
+
+        /*
+         * Prints new lines to make the output a little easier to read when debugging.
+         *
+         * @param tag The HTML tag being handled.         
+         *
+         */
+        private void formatLine(HTML.Tag tag)
+        {
+            try
+            {
+                if (tag.isBlock() || 
+                    tag.breaksFlow() || 
+                    tag == HTML.Tag.FRAME ||
+                    tag == HTML.Tag.FRAMESET ||
+                    tag == HTML.Tag.SCRIPT)
+                {
+                    write(lineSeparator);
+                }
+                
+            }                    
+            catch (Exception e)
+            {
+                log.error("Format Line tag parsing error", e);                    
+            }
+            
+        }
+
+
+        /*
+         * Used to write tag and attribute objects to the output stream.
+         * Returns a reference to itself so that these calls can be chained.
+         *
+         * @param txt Any text to be written out to stream with toString method.
+         *            The object being written should implement its toString method.
+         * @return A handle to the this, the callback, for chaining results.
+         *
+         */
+        private Callback addToResult(Object txt)
+        {
+            // to allow for implementation using Stringbuffer or StringWriter
+            // I don't know yet, which one is better in this case
+            //if (ignoreLevel > 0 ) return this;
+
+            try
+            {
+                write(txt.toString());
+            } 
+            catch (Exception e)
+            {
+                System.err.println("Error parsing:" + e);
+            }
+            return this;
+        }
+
+
+        /*
+         * Used to write all character content to the output stream.
+         * Returns a reference to itself so that these calls can be chained.
+         *
+         * @param txt Any character text to be written out directly to stream.
+         * @return A handle to the this, the callback, for chaining results.
+         *
+         */
+        private Callback addToResult(char[] txt)
+        {
+            //if (ignoreLevel > 0) return this;
+
+            try
+            {
+                if (writer != null)
+                {
+                    writer.write(txt);
+                }
+
+            } 
+            catch (Exception e)
+            { /* ignore */
+            }
+            return this;
+        }
+
+        /* 
+         * Accessor to the Callback's content-String
+         *
+         * @return Cleaned and rewritten HTML-Content
+         */        
+        public void getResult() 
+        {
+            try
+            {
+                if (writer != null)
+                {
+                    writer.flush();
+                }
+            } 
+            catch (Exception e)
+            { /* ignore */
+            }
+
+            // WARNING: doesn't work, if you remove " " + ... but don't know why
+            //String res = " " + result.toString(); 
+
+            // return res;
+        }
+
+        /*
+         * Flushes the output stream. NOT IMPLEMENTED
+         *
+         */
+        public void flush() throws javax.swing.text.BadLocationException 
+        {
+            // nothing to do here ...
+        }
+
+        /*
+         * Writes output to the final stream for all attributes of a given tag.
+         *
+         * @param tag The HTML tag being output.
+         * @param attrs The mutable HTML attribute set for the current HTML tag.
+         *
+         */
+        private void appendTagToResult(HTML.Tag tag, MutableAttributeSet attrs) 
+        {
+            convertURLS(tag, attrs);
+            Enumeration e = attrs.getAttributeNames();
+            addToResult("<").addToResult(tag);
+            while (e.hasMoreElements())
+            {
+                Object attr = e.nextElement();
+                String value = attrs.getAttribute(attr).toString();
+                addToResult(" ").addToResult(attr).addToResult("=\"").
+                addToResult(value).addToResult("\"");
+            }        
+            if (simpleTag)
+                addToResult("/>");
+            else             
+                addToResult(">");
+        }
+
+
+        /*
+         * Determines which HTML Tag/Element is being inspected, and calls the 
+         * appropriate converter for that context.  This method contains all the
+         * logic for determining how tags are rewritten. 
+         *
+         * @param tag TAG from the Callback-Interface.
+         * @param attrs The mutable HTML attribute set for the current HTML element.
+         */
+
+        private void convertURLS( HTML.Tag tag, MutableAttributeSet attrs ) 
+        {
+            rewriter.enterConvertTagEvent(tag.toString(), new SwingAttributes(attrs));
+
+            /*
+              if ( removeScript && (tag == HTML.Tag.SCRIPT)) {
+                ignoreLevel ++;
+              */
+        }
+
+        /*
+         * Determines which HTML Tag/Element is being inspected, and calls the 
+         * appropriate converter for that context.  This method contains all the
+         * logic for determining how text is rewritten. 
+         *
+         * @param tag TAG from the Callback-Interface.
+         * @param text The text for the current HTML element.
+         */
+
+        private String convertText(String tag, String text) 
+        {
+            return rewriter.enterConvertTextEvent(tag.toString(), text);
+        }
+    }
+    
+}

Added: portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/html/neko/CallbackElementRemover.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/html/neko/CallbackElementRemover.java?rev=1618527&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/html/neko/CallbackElementRemover.java (added)
+++ portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/html/neko/CallbackElementRemover.java Sun Aug 17 22:58:18 2014
@@ -0,0 +1,226 @@
+/*
+ * 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.portals.applications.webcontent2.portlet.rewriter.html.neko;
+
+import java.util.Stack;
+
+import org.apache.portals.applications.webcontent2.portlet.rewriter.Rewriter;
+import org.apache.xerces.xni.Augmentations;
+import org.apache.xerces.xni.QName;
+import org.apache.xerces.xni.XMLAttributes;
+import org.apache.xerces.xni.XMLString;
+import org.apache.xerces.xni.XNIException;
+import org.cyberneko.html.filters.ElementRemover;
+
+/**
+ * <p>
+ * CallbackElementRemover
+ * </p>
+ * <p>
+ *  Extended version of the NekoHTML ElementRemover which provides
+ *  tag stripping/removal based on Rewriter settings.
+ * </p>
+ * 
+ * @author <a href="mailto:weaver@apache.org">Scott T. Weaver </a>
+ * @version $Id: CallbackElementRemover.java 891414 2009-12-16 20:19:02Z rwatler $
+ *  
+ */
+public class CallbackElementRemover extends ElementRemover
+{
+
+    private Rewriter rewriter;
+    private Stack tagStack = new Stack();
+
+    /**
+     * Construct with reference to the rewriter context to consult for rewriting advice
+     */
+    public CallbackElementRemover( Rewriter rewriter )
+    {
+        super();
+        this.rewriter = rewriter;
+    }
+    
+    
+    // Base Class Protocol
+    
+    /**
+     * <p>
+     * characters
+     * </p>
+     * 
+     * @see org.apache.xerces.xni.XMLDocumentHandler#characters(org.apache.xerces.xni.XMLString text, org.apache.xerces.xni.Augmentations augs)
+     * @param text
+     * @param augs
+     * @throws org.apache.xerces.xni.XNIException
+     */
+    public void characters(XMLString text,Augmentations augs) throws XNIException
+    {
+        if (!tagStack.isEmpty())
+        {
+            String tag = (String)tagStack.peek();
+            processText(tag, text);
+        }
+        super.characters(text, augs);
+    }
+
+    /**
+     * <p>
+     * comment
+     * </p>
+     * 
+     * @see org.apache.xerces.xni.XMLDocumentHandler#comment(org.apache.xerces.xni.XMLString text, org.apache.xerces.xni.Augmentations augs)
+     * @param text
+     * @param augs
+     * @throws org.apache.xerces.xni.XNIException
+     */
+    public void comment(XMLString text,Augmentations augs) throws XNIException
+    {
+        if (rewriter.shouldRemoveComments())
+            return;
+        super.comment(text,augs);
+    }
+
+    /**
+     * <p>
+     * emptyElement
+     * </p>
+     * 
+     * @see org.apache.xerces.xni.XMLDocumentHandler#emptyElement(org.apache.xerces.xni.QName,
+     *      org.apache.xerces.xni.XMLAttributes,
+     *      org.apache.xerces.xni.Augmentations)
+     * @param element
+     * @param arg1
+     * @param arg2
+     * @throws org.apache.xerces.xni.XNIException
+     */
+    public void emptyElement( QName element, XMLAttributes attrs, Augmentations arg2 ) throws XNIException
+    {
+        String tag = element.rawname.toLowerCase();
+        processTag(tag,attrs) ;
+        super.emptyElement(element, attrs, arg2);
+    }
+
+    /**
+     * <p>
+     * startElement
+     * </p>
+     * 
+     * @see org.apache.xerces.xni.XMLDocumentHandler#startElement(org.apache.xerces.xni.QName,
+     *      org.apache.xerces.xni.XMLAttributes,
+     *      org.apache.xerces.xni.Augmentations)
+     * @param element
+     * @param arg1
+     * @param arg2
+     * @throws org.apache.xerces.xni.XNIException
+     */
+    public void startElement( QName element, XMLAttributes attrs, Augmentations arg2 ) throws XNIException
+    {
+        String tag = element.rawname.toLowerCase();
+        tagStack.push(tag);
+        processTag(tag,attrs);
+        super.startElement(element, attrs, arg2);
+    }
+    
+    /**
+     * <p>
+     * endElement
+     * </p>
+     * 
+     * @see org.apache.xerces.xni.XMLDocumentHandler#endElement(org.apache.xerces.xni.QName,
+     *      org.apache.xerces.xni.Augmentations)
+     * @param element
+     * @param arg1
+     * @throws org.apache.xerces.xni.XNIException
+     */
+    public void endElement( QName element, Augmentations arg1 ) throws XNIException
+    {
+        String tag = element.rawname.toLowerCase();
+        if (!tagStack.isEmpty() && tag.equals(tagStack.peek()))
+        {
+            tagStack.pop();
+        }
+        super.endElement(element, arg1);
+    }
+    
+    // Support Methods
+
+    /**
+     * <p>
+     * processTag
+     * </p>
+     * 
+     * @param tag
+     * @param attrs
+     */
+    protected void processTag(String tag, XMLAttributes attrs)
+    {
+        if (fRemovedElements.contains(tag))
+        {
+            // already removed
+            return ;
+        }
+        else if (rewriter.shouldStripTag(tag))
+        {
+            // first time for this tag...
+            // strip - remove tag and any text associated with it
+            removeElement(tag);
+            return ;
+        }
+        else if (rewriter.shouldRemoveTag(tag))
+        {
+            // BOZO - block intentionally left EMPTY
+            
+            // first time for this tag...
+            // remove - no directive necessary, the default behavior of ElementRemover is to drop tags that it does not know about (but the assocated text will remain)
+            return ;
+        }
+
+        // OTHERWISE - explicitly accept (keep tag and associated text)
+        // NOTE: even if fAcceptedElements contains the tag already, we need to reset the attribute names for this invocation context
+        rewriter.enterConvertTagEvent(tag,new XMLAttributesWrapper(attrs));
+        acceptElement(tag,getAttributeNames(attrs));
+    }
+    protected String[] getAttributeNames(XMLAttributes attrs)
+    {
+        int length = attrs != null ? attrs.getLength() : 0 ;
+        String[] names = length > 0 ? new String[ length ] : null ;
+        
+        for( int i = 0, limit = length;i<limit;i++)
+        {
+            names[i] = attrs.getQName(i) ;
+        }
+        return names ;
+    }
+
+    /**
+     * <p>
+     * processText
+     * </p>
+     * 
+     * @param tag
+     * @param text
+     */
+    protected void processText(String tag, XMLString text)
+    {
+        String convertedText = rewriter.enterConvertTextEvent(tag, new String(text.ch, text.offset, text.length));
+        if (convertedText != null)
+        {
+            char [] convertedTextChars = convertedText.toCharArray();
+            text.setValues(convertedTextChars, 0, convertedTextChars.length);
+        }
+    }
+}

Added: portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/html/neko/NekoHTMLParserAdapter.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/html/neko/NekoHTMLParserAdapter.java?rev=1618527&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/html/neko/NekoHTMLParserAdapter.java (added)
+++ portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/html/neko/NekoHTMLParserAdapter.java Sun Aug 17 22:58:18 2014
@@ -0,0 +1,74 @@
+/*
+ * 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.portals.applications.webcontent2.portlet.rewriter.html.neko;
+
+import java.io.Reader;
+import java.io.Writer;
+
+import org.apache.portals.applications.webcontent2.portlet.rewriter.ParserAdaptor;
+import org.apache.portals.applications.webcontent2.portlet.rewriter.Rewriter;
+import org.apache.portals.applications.webcontent2.portlet.rewriter.RewriterException;
+
+/**
+ * <p>
+ * NeckoHTMLParserAdapter
+ * </p>
+ * <p>
+ *  
+ * </p>
+ * @author <a href="mailto:weaver@apache.org">Scott T. Weaver</a>
+ * @version $Id: NekoHTMLParserAdapter.java 764612 2009-04-13 21:17:59Z taylor $
+ *
+ */
+public class NekoHTMLParserAdapter implements ParserAdaptor
+{
+
+  
+    /**
+     * <p>
+     * parse
+     * </p>
+     *
+     * @see org.apache.portals.applications.webcontent.rewriter.ParserAdaptor#parse(org.apache.portals.applications.webcontent.rewriter.Rewriter, java.io.Reader)
+     * @param rewriter
+     * @param reader
+     * @throws RewriterException
+     */
+    public void parse( Rewriter rewriter, Reader reader ) throws RewriterException
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+    /**
+     * <p>
+     * rewrite
+     * </p>
+     *
+     * @see org.apache.portals.applications.webcontent.rewriter.ParserAdaptor#rewrite(org.apache.portals.applications.webcontent.rewriter.Rewriter, java.io.Reader, java.io.Writer)
+     * @param rewriter
+     * @param reader
+     * @param writer
+     * @throws RewriterException
+     */
+    public void rewrite( Rewriter rewriter, Reader reader, Writer writer ) throws RewriterException
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+}

Added: portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/html/neko/NekoParserAdaptor.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/html/neko/NekoParserAdaptor.java?rev=1618527&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/html/neko/NekoParserAdaptor.java (added)
+++ portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/html/neko/NekoParserAdaptor.java Sun Aug 17 22:58:18 2014
@@ -0,0 +1,126 @@
+/*
+ * 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.portals.applications.webcontent2.portlet.rewriter.html.neko;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.apache.portals.applications.webcontent2.portlet.rewriter.ParserAdaptor;
+import org.apache.portals.applications.webcontent2.portlet.rewriter.Rewriter;
+import org.apache.portals.applications.webcontent2.portlet.rewriter.RewriterException;
+import org.apache.xerces.xni.parser.XMLDocumentFilter;
+import org.apache.xerces.xni.parser.XMLInputSource;
+import org.cyberneko.html.filters.DefaultFilter;
+import org.cyberneko.html.filters.Purifier;
+import org.cyberneko.html.parsers.SAXParser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.SAXException;
+
+
+/**
+ * <p>
+ * NekoParserAdapter
+ * </p>
+ * <p>
+ *  
+ * </p>
+ * @author <a href="mailto:dyoung@phase2systems.com">David L Young</a>
+ * @version $Id: NekoParserAdaptor.java 771536 2009-05-05 03:29:47Z ate $
+ *
+ */
+public class NekoParserAdaptor implements ParserAdaptor
+{
+    protected final static Logger log = LoggerFactory.getLogger(NekoParserAdaptor.class);
+    
+    /*
+     * Construct a cyberneko HTML parser adaptor
+     */
+    public NekoParserAdaptor()
+    {
+        super();
+    }
+    
+    /**
+     * <p>
+     * parse
+     * </p>
+     *
+     * @see org.apache.portals.applications.webcontent.rewriter.ParserAdaptor#parse(org.apache.portals.applications.webcontent.rewriter.Rewriter, java.io.Reader)
+     * @param rewriter
+     * @param reader
+     * @throws RewriterException
+     */
+    public void parse(Rewriter rewriter, Reader reader)
+            throws RewriterException
+    {
+        // not sure what this means to parse without rewriting
+        rewrite(rewriter,reader,null);
+    }
+
+    /**
+     * <p>
+     * rewrite
+     * </p>
+     *
+     * @see org.apache.portals.applications.webcontent.rewriter.ParserAdaptor#rewrite(org.apache.portals.applications.webcontent.rewriter.Rewriter, java.io.Reader, java.io.Writer)
+     * @param rewriter
+     * @param reader
+     * @param writer
+     * @throws RewriterException
+     */
+    public void rewrite(Rewriter rewriter, java.io.Reader reader, java.io.Writer writer)
+            throws RewriterException
+    {
+        // use a cyberneko SAXParser
+        SAXParser parser = new SAXParser() ;
+
+        // setup filter chain
+        XMLDocumentFilter[] filters = {
+            new Purifier(),                                                                                  // [1] standard neko purifications (tag balancing, etc)
+            new CallbackElementRemover( rewriter ),                                                          // [2] accept / reject tags based on advice from rewriter
+            writer != null ? new org.cyberneko.html.filters.Writer( writer, null ) : new DefaultFilter()     // [3] propagate results to specified writer (or do nothing -- Default -- when writer is null)
+        };
+        
+        String filtersPropName = "http://cyberneko.org/html/properties/filters";
+   
+        try
+        {
+            parser.setProperty(filtersPropName, filters);
+        }
+        catch (SAXException e)
+        {
+            // either no longer supported (SAXNotSupportedException), or no logner recognized (SAXNotRecognizedException)
+            log.error(filtersPropName + " is, unexpectedly, no longer defined for the cyberneko HTML parser",e);
+            throw new RewriterException("cyberneko parser version not supported",e);
+        }
+
+        try
+        {
+            // parse from reader
+            parser.parse(new XMLInputSource( null, null, null, reader, null )) ;
+        }
+        catch (IOException e)
+        {
+            String msg = "cyberneko HTML parsing failure";
+            log.error(msg,e);
+            throw new RewriterException(msg,e);
+        }
+
+    }
+
+}

Added: portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/html/neko/URLRewriterFilter.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/html/neko/URLRewriterFilter.java?rev=1618527&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/html/neko/URLRewriterFilter.java (added)
+++ portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/html/neko/URLRewriterFilter.java Sun Aug 17 22:58:18 2014
@@ -0,0 +1,181 @@
+/*
+ * 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.portals.applications.webcontent2.portlet.rewriter.html.neko;
+
+import org.apache.portals.applications.webcontent2.portlet.rewriter.Rewriter;
+import org.apache.xerces.xni.Augmentations;
+import org.apache.xerces.xni.QName;
+import org.apache.xerces.xni.XMLAttributes;
+import org.apache.xerces.xni.XMLString;
+import org.apache.xerces.xni.XNIException;
+import org.cyberneko.html.filters.DefaultFilter;
+
+/**
+ * <p>
+ * URLRewriterFilter
+ * </p>
+ * <p>
+ * 
+ * </p>
+ * 
+ * @author <a href="mailto:weaver@apache.org">Scott T. Weaver </a>
+ * @version $Id: URLRewriterFilter.java 764612 2009-04-13 21:17:59Z taylor $
+ *  
+ */
+public class URLRewriterFilter extends DefaultFilter
+{
+    
+    private Rewriter rewriter; 
+    
+    
+    /**
+     *  
+     */
+    public URLRewriterFilter(Rewriter rewriter )
+    {
+        super();
+        this.rewriter = rewriter;
+    }
+        
+
+    /**
+     * <p>
+     * startElement
+     * </p>
+     * 
+     * @see org.apache.xerces.xni.XMLDocumentHandler#startElement(org.apache.xerces.xni.QName,
+     *      org.apache.xerces.xni.XMLAttributes,
+     *      org.apache.xerces.xni.Augmentations)
+     * @param element
+     * @param attrs
+     * @param augs
+     * @throws org.apache.xerces.xni.XNIException
+     */
+    public void startElement( QName element, XMLAttributes attrs, Augmentations augs ) throws XNIException
+    {
+        if (false == rewriter.enterSimpleTagEvent(element.rawname, new XMLAttributesWrapper(attrs)))
+        {
+            doRewrite(element, attrs);
+            String appended = rewriter.exitSimpleTagEvent(element.rawname, new XMLAttributesWrapper(attrs));
+            if (null != appended)
+            {
+              //TODO: implement this!
+            }
+        }
+        
+        super.startElement(element, attrs, augs);
+    }
+
+    /**
+     * <p>
+     * doRewrite
+     * </p>
+     *
+     * @param element
+     * @param attrs
+     */
+    protected void doRewrite( QName element, XMLAttributes attrs )
+    {
+        if (element.rawname.equals("A"))
+        {            
+            rewriteAttribute("href", attrs);
+        }
+        else if (element.rawname.equals("FORM"))
+        {            
+            rewriteAttribute("action", attrs);
+        }
+    }
+
+    protected void rewriteAttribute( String attrName, XMLAttributes attributes )
+    {
+
+        String uri = attributes.getValue(attrName);
+        
+        
+        if (uri != null)
+        {
+               // attributes.setValue(attributes.getIndex(attrName), urlGenerator.createUrl(uri));
+         
+        }
+
+    }
+    /**
+     * <p>
+     * emptyElement
+     * </p>
+     *
+     * @see org.apache.xerces.xni.XMLDocumentHandler#emptyElement(org.apache.xerces.xni.QName, org.apache.xerces.xni.XMLAttributes, org.apache.xerces.xni.Augmentations)
+     * @param arg0
+     * @param arg1
+     * @param arg2
+     * @throws org.apache.xerces.xni.XNIException
+     */
+    public void emptyElement( QName element, XMLAttributes attrs, Augmentations arg2 ) throws XNIException
+    {
+        doRewrite(element, attrs);
+        super.emptyElement(element, attrs, arg2);
+    }
+    /**
+     * <p>
+     * comment
+     * </p>
+     *
+     * @see org.apache.xerces.xni.XMLDocumentHandler#comment(org.apache.xerces.xni.XMLString, org.apache.xerces.xni.Augmentations)
+     * @param comment
+     * @param augs
+     * @throws org.apache.xerces.xni.XNIException
+     */
+    public void comment( XMLString comment, Augmentations augs ) throws XNIException
+    {
+        if (!rewriter.shouldRemoveComments())
+        {
+            super.comment(comment, augs);                  
+        }
+        
+    }
+    /**
+     * <p>
+     * endElement
+     * </p>
+     *
+     * @see org.apache.xerces.xni.XMLDocumentHandler#endElement(org.apache.xerces.xni.QName, org.apache.xerces.xni.Augmentations)
+     * @param arg0
+     * @param arg1
+     * @throws org.apache.xerces.xni.XNIException
+     */
+    public void endElement( QName element, Augmentations augs ) throws XNIException
+    {
+        super.endElement(element, augs);
+    }
+    /**
+     * <p>
+     * characters
+     * </p>
+     *
+     * @see org.apache.xerces.xni.XMLDocumentHandler#characters(org.apache.xerces.xni.XMLString, org.apache.xerces.xni.Augmentations)
+     * @param arg0
+     * @param arg1
+     * @throws org.apache.xerces.xni.XNIException
+     */
+    public void characters( XMLString text, Augmentations arg1 ) throws XNIException
+    {        
+        if (!(text.ch[0] == '>') && ! rewriter.enterText(text.ch, text.offset))
+        {                            
+            super.characters(text, arg1);
+        }         
+    }
+}
\ No newline at end of file

Added: portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/html/neko/XMLAttributesWrapper.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/html/neko/XMLAttributesWrapper.java?rev=1618527&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/html/neko/XMLAttributesWrapper.java (added)
+++ portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/html/neko/XMLAttributesWrapper.java Sun Aug 17 22:58:18 2014
@@ -0,0 +1,464 @@
+/*
+ * 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.portals.applications.webcontent2.portlet.rewriter.html.neko;
+
+import org.apache.portals.applications.webcontent2.portlet.rewriter.MutableAttributes;
+import org.apache.xerces.xni.Augmentations;
+import org.apache.xerces.xni.QName;
+import org.apache.xerces.xni.XMLAttributes;
+
+/**
+ * <p>
+ * XMLAttributesWrapper
+ * </p>
+ * <p>
+ *
+ * </p>
+ * @author <a href="mailto:weaver@apache.org">Scott T. Weaver</a>
+ * @version $Id: XMLAttributesWrapper.java 764612 2009-04-13 21:17:59Z taylor $
+ *
+ */
+public class XMLAttributesWrapper implements MutableAttributes
+{
+    protected XMLAttributes attrs;
+    
+    /**
+     * 
+     */
+    public XMLAttributesWrapper(XMLAttributes attrs)
+    {
+        super();
+        this.attrs = attrs;
+    }
+
+    /**
+     * <p>
+     * addAttribute
+     * </p>
+     *
+     * @param arg0
+     * @param arg1
+     * @param arg2
+     * @return
+     */
+    public int addAttribute( QName arg0, String arg1, String arg2 )
+    {
+        int i = getIndex( arg0.rawname );
+        if ( i >= 0 )
+             attrs.removeAttributeAt( i );
+         
+        return attrs.addAttribute( arg0, arg1, arg2 );
+    }
+    /**
+     * <p>
+     * equals
+     * </p>
+     *
+     * @see java.lang.Object#equals(java.lang.Object)
+     * @param obj
+     * @return
+     */
+    public boolean equals( Object obj )
+    {
+        return attrs.equals(obj);
+    }
+    /**
+     * <p>
+     * getAugmentations
+     * </p>
+     *
+     * @param arg0
+     * @return
+     */
+    public Augmentations getAugmentations( int arg0 )
+    {
+        return attrs.getAugmentations(arg0);
+    }
+    /**
+     * <p>
+     * getAugmentations
+     * </p>
+     *
+     * @param arg0
+     * @return
+     */
+    public Augmentations getAugmentations( String qName )
+    {
+        return attrs.getAugmentations(asNekoAttributeName(qName)) ;
+    }
+    /**
+     * <p>
+     * getAugmentations
+     * </p>
+     *
+     * @param arg0
+     * @param arg1
+     * @return
+     */
+    public Augmentations getAugmentations( String uri, String localPart )
+    {
+        return attrs.getAugmentations(uri,asNekoAttributeName(localPart));
+    }
+    /**
+     * <p>
+     * getIndex
+     * </p>
+     *
+     * @param arg0
+     * @return
+     */
+    public int getIndex( String qName )
+    {
+        return attrs.getIndex(asNekoAttributeName(qName));
+    }
+    /**
+     * <p>
+     * getIndex
+     * </p>
+     *
+     * @param arg0
+     * @param arg1
+     * @return
+     */
+    public int getIndex( String uri, String localName )
+    {
+        return attrs.getIndex(uri,asNekoAttributeName(localName));
+    }
+    /**
+     * <p>
+     * getLength
+     * </p>
+     *
+     * @return
+     */
+    public int getLength()
+    {
+        return attrs.getLength();
+    }
+    /**
+     * <p>
+     * getLocalName
+     * </p>
+     *
+     * @param arg0
+     * @return
+     */
+    public String getLocalName( int arg0 )
+    {
+        return attrs.getLocalName(arg0);
+    }
+    /**
+     * <p>
+     * getName
+     * </p>
+     *
+     * @param arg0
+     * @param arg1
+     */
+    public void getName( int arg0, QName arg1 )
+    {
+        attrs.getName(arg0, arg1);
+    }
+    /**
+     * <p>
+     * getNonNormalizedValue
+     * </p>
+     *
+     * @param arg0
+     * @return
+     */
+    public String getNonNormalizedValue( int arg0 )
+    {
+        return attrs.getNonNormalizedValue(arg0);
+    }
+    /**
+     * <p>
+     * getPrefix
+     * </p>
+     *
+     * @param arg0
+     * @return
+     */
+    public String getPrefix( int arg0 )
+    {
+        return attrs.getPrefix(arg0);
+    }
+    /**
+     * <p>
+     * getQName
+     * </p>
+     *
+     * @param arg0
+     * @return
+     */
+    public String getQName( int arg0 )
+    {
+        return attrs.getQName(arg0);
+    }
+    /**
+     * <p>
+     * getType
+     * </p>
+     *
+     * @param arg0
+     * @return
+     */
+    public String getType( int arg0 )
+    {
+        return attrs.getType(arg0);
+    }
+    /**
+     * <p>
+     * getType
+     * </p>
+     *
+     * @param arg0
+     * @return
+     */
+    public String getType( String qName )
+    {
+        return attrs.getType(asNekoAttributeName(qName));
+    }
+    /**
+     * <p>
+     * getType
+     * </p>
+     *
+     * @param arg0
+     * @param arg1
+     * @return
+     */
+    public String getType( String uri, String localName )
+    {
+        return attrs.getType(uri, asNekoAttributeName(localName));
+    }
+    /**
+     * <p>
+     * getURI
+     * </p>
+     *
+     * @param arg0
+     * @return
+     */
+    public String getURI( int arg0 )
+    {
+        return attrs.getURI(arg0);
+    }
+    /**
+     * <p>
+     * getValue
+     * </p>
+     *
+     * @param arg0
+     * @return
+     */
+    public String getValue( int arg0 )
+    {
+        return attrs.getValue(arg0);
+    }
+    /**
+     * <p>
+     * getValue
+     * </p>
+     *
+     * @param arg0
+     * @return
+     */
+    public String getValue( String qName )
+    {
+        return attrs.getValue(asNekoAttributeName(qName));
+    }
+    /**
+     * <p>
+     * getValue
+     * </p>
+     *
+     * @param arg0
+     * @param arg1
+     * @return
+     */
+    public String getValue( String uri, String localName )
+    {
+        return attrs.getValue(uri, asNekoAttributeName(localName));
+    }
+    /**
+     * <p>
+     * hashCode
+     * </p>
+     *
+     * @see java.lang.Object#hashCode()
+     * @return
+     */
+    public int hashCode()
+    {
+        return attrs.hashCode();
+    }
+    /**
+     * <p>
+     * isSpecified
+     * </p>
+     *
+     * @param arg0
+     * @return
+     */
+    public boolean isSpecified( int arg0 )
+    {
+        return attrs.isSpecified(arg0);
+    }
+    /**
+     * <p>
+     * removeAllAttributes
+     * </p>
+     *
+     * 
+     */
+    public void removeAllAttributes()
+    {
+        attrs.removeAllAttributes();
+    }
+    /**
+     * <p>
+     * removeAttributeAt
+     * </p>
+     *
+     * @param arg0
+     */
+    public void removeAttributeAt( int arg0 )
+    {
+        attrs.removeAttributeAt(arg0);
+    }
+    /**
+     * <p>
+     * setAugmentations
+     * </p>
+     *
+     * @param arg0
+     * @param arg1
+     */
+    public void setAugmentations( int arg0, Augmentations arg1 )
+    {
+        attrs.setAugmentations(arg0, arg1);
+    }
+    /**
+     * <p>
+     * setName
+     * </p>
+     *
+     * @param arg0
+     * @param arg1
+     */
+    public void setName( int arg0, QName arg1 )
+    {
+        attrs.setName(arg0, arg1);
+    }
+    /**
+     * <p>
+     * setNonNormalizedValue
+     * </p>
+     *
+     * @param arg0
+     * @param arg1
+     */
+    public void setNonNormalizedValue( int arg0, String arg1 )
+    {
+        attrs.setNonNormalizedValue(arg0, arg1);
+    }
+    /**
+     * <p>
+     * setSpecified
+     * </p>
+     *
+     * @param arg0
+     * @param arg1
+     */
+    public void setSpecified( int arg0, boolean arg1 )
+    {
+        attrs.setSpecified(arg0, arg1);
+    }
+    /**
+     * <p>
+     * setType
+     * </p>
+     *
+     * @param arg0
+     * @param arg1
+     */
+    public void setType( int arg0, String arg1 )
+    {
+        attrs.setType(arg0, arg1);
+    }
+    /**
+     * <p>
+     * setValue
+     * </p>
+     *
+     * @param arg0
+     * @param arg1
+     */
+    public void setValue( int arg0, String arg1 )
+    {
+        attrs.setValue(arg0, arg1);
+    }
+    /**
+     * <p>
+     * toString
+     * </p>
+     *
+     * @see java.lang.Object#toString()
+     * @return
+     */
+    public String toString()
+    {
+        return attrs.toString();
+    }
+    /**
+     * <p>
+     * addAttribute
+     * </p>
+     *
+     * @see org.apache.portals.applications.webcontent.rewriter.MutableAttributes#addAttribute(java.lang.String, java.lang.Object)
+     * @param name
+     * @param value
+     */
+    public void addAttribute( String name, Object value )
+    {
+        QName qName = null ;
+        int i = name.indexOf(':');
+        if (i < 0)
+        {
+            name = name.toLowerCase();
+            qName = new QName(null,name,name,null);
+        }
+        else
+        {
+            String prefix = name.substring(0,i);
+            String localPart = name.substring(i+1).toLowerCase();
+            name = name.toLowerCase();
+            qName = new QName(prefix,localPart,name,null);
+        }
+        addAttribute(qName,"CDATA",value.toString());
+    }
+    
+    
+    // Support Methods
+    
+    protected String asNekoAttributeName(String n)
+    {
+        // neko, by default, converts attribute names to lower case
+        return n != null ? n.toLowerCase() : null ;
+    }
+}

Added: portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/rules/Attribute.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/rules/Attribute.java?rev=1618527&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/rules/Attribute.java (added)
+++ portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/rules/Attribute.java Sun Aug 17 22:58:18 2014
@@ -0,0 +1,40 @@
+/*
+ * 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.portals.applications.webcontent2.portlet.rewriter.rules;
+
+/**
+ * Attribute
+ *
+ * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
+ * @version $Id: Attribute.java 764612 2009-04-13 21:17:59Z taylor $
+ */
+public interface Attribute extends Identified
+{
+    /**
+     * Get the rewriter rule associated with this attribute.
+     * 
+     * @return The rewriter rule.
+     */
+    Rule getRule();
+    
+    /**
+     * Set the rewriter rule associated with this attribute.
+     * 
+     * @param rule The rewriter rule.
+     */    
+    void setRule(Rule rule);
+}

Added: portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/rules/Identified.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/rules/Identified.java?rev=1618527&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/rules/Identified.java (added)
+++ portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/rewriter/rules/Identified.java Sun Aug 17 22:58:18 2014
@@ -0,0 +1,41 @@
+/*
+ * 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.portals.applications.webcontent2.portlet.rewriter.rules;
+
+/**
+ * Identified
+ *
+ * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
+ * @version $Id: Identified.java 764612 2009-04-13 21:17:59Z taylor $
+ */
+public interface Identified
+{
+    /**
+     * Get the unique identification string for this rule.
+     * 
+     * @return the unique identifier of the rule 
+     */
+    String getId();
+    
+    /**
+     * Set the unique identification string for this rule.
+     * 
+     * @param id the unique identifier of the rule 
+     */
+    void setId(String id);
+    
+}