/*
 * $Header: /home/cvspublic/jakarta-slide/proposals/tamino/src/store/org/apache/slide/store/tamino/tools/stores/ActionDeclaration.java,v 1.3 2004/07/30 06:52:06 ozeigermann Exp $
 * $Revision: 1.3 $
 * $Date: 2004/07/30 06:52:06 $
 *
 * ====================================================================
 *
 * Copyright 1999-2004 The Apache Software Foundation.
 *
 * Licensed 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.slide.store.tamino.tools.stores;

import java.util.ArrayList;
import java.util.List;
import org.apache.slide.urm.URMException;
import org.apache.slide.urm.accesscontroler.URMAclAdministrator;
import org.apache.slide.urm.accesscontroler.URMAction;
import org.apache.slide.urm.common.URMPrincipal;
import org.apache.slide.util.Strings;
import org.apache.slide.util.XAssertionFailed;

/**
 ** @author michael.hartmeier@softwareag.com
 ** @version $Revision: 1.3 $
 **/

public class ActionDeclaration {
    public static final String SCOPE = "/administration/security/actions";
    
    //-- public interface
    
    public static void defineAllUrm(URMPrincipal principal) throws URMException {
        int i;
        URMAclAdministrator admin;
        List stack;

        admin = principal.getURMAclAdministrator();
        stack = new ArrayList();
        for (i = 0; i < all.length; i++) {
            all[i].defineUrm(stack, admin);
        }
    }
    
    public static String allToXml() {
        int i;
        StringBuffer b;
        
        b = new StringBuffer();
        for (i = 0; i < all.length; i++) {
            b.append(all[i].toXml());
        }
        return b.toString();
    }

    //--
    
    private static final ActionDeclaration[] all;
    
    static {
        int i;

        all = new ActionDeclaration[] {
            create("read", "read-acl read-current-user-privilege-set"),
            create("read-acl", ""),
            create("read-current-user-privilege-set", ""),
            create("write", "write-acl write-properties write-content"),
            create("write-acl", ""),
            create("write-properties", ""),
            create("write-content", "bind unbind"),
            create("bind", ""),
            create("unbind", ""),
            create("unlock", "")
        };
        for (i = 0; i < all.length; i++) {
            all[i].validate();
        }
    }

    private static ActionDeclaration create(String name, String childrenLst) {
        return new ActionDeclaration(name, Strings.split(childrenLst, " "));
    }
    
    /** @return never null */
    private static ActionDeclaration get(String name) {
        ActionDeclaration a;
        
        a = lookup(name);
        if (a == null) {
            throw new XAssertionFailed("no such action: " + name);
        }
        return a;
    }
    
    public static ActionDeclaration lookup(String name) {
        int i;
        
        for (i = 0; i < all.length; i++) {
            if (all[i].name.equals(name)) {
                return all[i];
            }
        }
        return null;
    }
    //--
    
    private final String name;
    private final String[] children;
    
    private ActionDeclaration(String name, String[] children) {
        this.name = name;
        this.children = children;
    }

    private void defineUrm(List stack, URMAclAdministrator admin) throws URMException {
        URMAction action;
        int i;
        String child;

        if (stack.contains(name)) {
            throw new XAssertionFailed("circular action definition: " + stack + " on name " + name);
        }
        stack.add(name);
        action = admin.getAction(name);
        if (action != null) {
            return;
        }
        action = admin.createAction(name);
        
        for (i = 0; i < children.length; i++) {
            child = children[i];
            get(child).defineUrm(stack, admin);
            action.addAction(child);
        }
        stack.remove(name);
    }
    
    private String toXml() {
        StringBuffer result;
        int i;
        
        result = new StringBuffer();
        result.append(
            "  <objectnode classname='org.apache.slide.structure.ActionNode' uri='" + SCOPE + "/" + name + "'>\n" +
                "    <revision>\n" +
                "      <property name='privilege-member-set'><![CDATA[\n");
        
        for (i = 0; i < children.length; i++) {
            result.append("<D:href xmlns:D='DAV:'>" + SCOPE);
            result.append('/');
            result.append(children[i]);
            result.append("</D:href>\n");
        }
        result.append(
            "        ]]>\n" +
                "      </property>\n" +
                "    </revision>\n" +
                "  </objectnode>\n");
        return result.toString();
    }
    
    private void validate() {
        int i;

        for (i = 0; i < children.length; i++) {
            get(children[i]);
        }
    }
}

