RoleFilterTransformer.java :  » Content-Management-System » apache-lenya-2.0 » org » apache » cocoon » transformation » Java Open Source

Java Open Source » Content Management System » apache lenya 2.0 
apache lenya 2.0 » org » apache » cocoon » transformation » RoleFilterTransformer.java
/*
 * 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.cocoon.transformation;

import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.caching.CacheableProcessingComponent;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.excalibur.source.SourceValidity;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

import java.io.IOException;
import java.util.Map;
import java.util.StringTokenizer;

/**
 * @cocoon.sitemap.component.documentation
 * Filter XML fragments based on a user's role.  This will help in
 * the development of smart forms that must only show information to
 * people who are logged in and have the correct role.  The Role is
 * specified by the Request semantics.  You can specify multiple roles
 * by using comma delimiting.
 * 
 * @cocoon.sitemap.component.name   role-filter
 * @cocoon.sitemap.component.logger sitemap.transformer.role-filter
 * 
 * Filter XML fragments based on a user's role.  This will help in
 * the development of smart forms that must only show information to
 * people who are logged in and have the correct role.  The Role is
 * specified by the Request semantics.  You can specify multiple roles
 * by using comma delimiting.
 *
 * <pre>
 *   &lt;root xmlns:roles="http://apache.org/cocoon/role-filter/1.0"&gt;
 *     &lt;textbox name="identifier" roles:restricted="admin,boss"/&gt;
 *     &lt;textbox name="name" roles:read-only="admin,boss"/&gt;
 *   &lt;/root&gt;
 * </pre>
 *
 * The previous example will only show the "identifier" textbox for the
 * roles "admin" and "boss".  It will pass role:read-only="" if the
 * roles "admin" or "boss" are accessing the page.  That way you can
 * specify any special processing by testing for the read-only attribute.
 * This filter does not care about the prefix, only the namespace URI.
 * That means you can reassign the namespace to another prefix and all
 * will work as expected.
 *
 * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
 * @version CVS $Id: RoleFilterTransformer.java 433543 2006-08-22 06:22:54Z crossley $
 */
public class RoleFilterTransformer
        extends AbstractTransformer
        implements CacheableProcessingComponent {
    private final static String URI = "http://apache.org/cocoon/role-filter/1.0";
    private final static String RESTRICT = "restricted";
    private final static String VIEW = "read-only";
    
    Request request = null;
    private int skipCounter = 0;
    
    public RoleFilterTransformer() {
    }

    public final void setup(SourceResolver resolver, Map objectModel, String src, Parameters params)
    throws ProcessingException, SAXException, IOException {
        this.request = ObjectModelHelper.getRequest(objectModel);
        this.skipCounter = 0;
    }

    /**
     * Disable caching
     */
    public java.io.Serializable getKey() {
        return null;
    }

    public final void startElement(String uri, String loc, String raw, Attributes a)
    throws SAXException {
        if (this.skipCounter > 0) {
            this.skipCounter++;
        } else {
            int roleIndex = a.getIndex(RoleFilterTransformer.URI, RoleFilterTransformer.RESTRICT);
            int viewIndex = a.getIndex(RoleFilterTransformer.URI, RoleFilterTransformer.VIEW);
            boolean propogate = true;
            boolean readOnly = false;

            if (roleIndex >= 0) {
                String roleRestriction = a.getValue(roleIndex);
                StringTokenizer roles = new StringTokenizer(roleRestriction, ",", false);
                propogate = false;

                while ((! propogate) && roles.hasMoreTokens()) {
                    if (request.isUserInRole(roles.nextToken())) {
                        propogate = true;
                    }
                }
            }

            if (propogate) {
                if (viewIndex >= 0) {
                    String viewRestriction = a.getValue(viewIndex);
                    StringTokenizer roles = new StringTokenizer(viewRestriction, ",", false);

                    while ((! readOnly) && roles.hasMoreTokens()) {
                        if (request.isUserInRole(roles.nextToken())) {
                            readOnly = true;
                        }
                    }
                }
                super.startElement(uri, loc, raw,
                        this.copyAttributes(a, roleIndex, viewIndex, readOnly));
            } else {
                this.skipCounter = 1;
            }
        }
    }

    public final void endElement(String uri, String loc, String raw)
    throws SAXException {
        if (skipCounter > 0) {
            skipCounter--; 
        } else {
            super.endElement(uri, loc, raw);
        }
    }

    private final Attributes copyAttributes(final Attributes a, final int role,
                                            final int view, boolean readOnly) {
        if (role < 0 && view < 0) {
            return a;
        }

        AttributesImpl attr = new AttributesImpl();
        attr.setAttributes(a);
        if (role >= 0) {
            attr.removeAttribute(role);
        }

        if (view >= 0) {
            if (readOnly) {
                attr.setValue(view, "");
            } else {
                attr.removeAttribute(view);
            }
        }

        return attr;
    }

    public void recycle() {
        this.request = null;
        super.recycle();
    }

    public void startEntity(String name) throws SAXException {
        if (this.skipCounter == 0)  {
            super.startEntity(name);
        }
    }

    public void endEntity(String name) throws SAXException {
        if (this.skipCounter == 0)  {
            super.endEntity(name);
        }
    }

    public void comment(char[] ch, int start, int len) throws SAXException {
        if (this.skipCounter == 0)  {
            super.comment(ch, start, len);
        }
    }

    public void characters(char[] c, int start, int len) throws SAXException {
        if (this.skipCounter == 0)  {
            super.characters(c, start, len);
        }
    }

    public void startCDATA() throws SAXException {
        if (this.skipCounter == 0) {
            super.startCDATA();
        }
    }

    public void processingInstruction(String target, String data) throws SAXException {
        if (this.skipCounter == 0)  {
            super.processingInstruction(target, data);
        }
    }

    public SourceValidity getValidity() {
        return null;
    }

    public void endCDATA() throws SAXException {
        if (this.skipCounter == 0) {
            super.endCDATA();
        }
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.