Package org.wso2.carbon.governance.registry.extensions.aspects

Source Code of org.wso2.carbon.governance.registry.extensions.aspects.DefaultLifeCycle

/*
* Copyright (c) 2006, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* 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.wso2.carbon.governance.registry.extensions.aspects;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.axiom.om.util.AXIOMUtil;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.util.XMLUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.scxml.io.SCXMLParser;
import org.apache.commons.scxml.model.*;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.w3c.dom.Element;
import org.wso2.carbon.governance.api.exception.GovernanceException;
import org.wso2.carbon.governance.api.services.ServiceManager;
import org.wso2.carbon.governance.api.services.dataobjects.Service;
import org.wso2.carbon.governance.registry.extensions.Interfaces.CustomValidations;
import org.wso2.carbon.governance.registry.extensions.beans.CheckItemBean;
import org.wso2.carbon.governance.registry.extensions.beans.PermissionsBean;
import org.wso2.carbon.governance.registry.extensions.beans.ScriptBean;
import org.wso2.carbon.governance.registry.extensions.beans.ValidationsBean;
import org.wso2.carbon.mashup.javascript.hostobjects.registry.CollectionHostObject;
import org.wso2.carbon.mashup.javascript.hostobjects.registry.RegistryHostObject;
import org.wso2.carbon.mashup.javascript.hostobjects.registry.ResourceHostObject;
import org.wso2.carbon.mashup.utils.MashupConstants;
import org.wso2.carbon.registry.core.*;
import org.wso2.carbon.registry.core.config.RegistryContext;
import org.wso2.carbon.registry.core.exceptions.RegistryException;
import org.wso2.carbon.registry.core.jdbc.handlers.RequestContext;
import org.wso2.carbon.registry.core.session.CurrentSession;
import org.wso2.carbon.registry.core.utils.RegistryUtils;
import org.wso2.carbon.registry.extensions.utils.CommonUtil;
import org.wso2.carbon.user.core.UserStoreException;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.ByteArrayInputStream;
import java.io.CharArrayReader;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.*;

import static org.apache.axiom.om.util.AXIOMUtil.stringToOM;
import static org.wso2.carbon.registry.extensions.utils.CommonUtil.setServiceVersion;
import static org.wso2.carbon.registry.extensions.utils.CommonUtil.setWSDLURL;


public class DefaultLifeCycle extends Aspect {
    private static final Log log = LogFactory.getLog(DefaultLifeCycle.class);
    private static final String REGISTRY_CUSTOM_LIFECYCLE_CHECKLIST_OPTION =
            "registry.custom_lifecycle.checklist.option.";
    private static final String REGISTRY_CUSTOM_LIFECYCLE_CHECKLIST_JS_SCRIPT_CONSOLE =
            "registry.custom_lifecycle.checklist.js.script.console.";

    //Default Service paths
    private static final String TRUNK = "trunk";
    private static String GOVERNANCE_PATH = RegistryConstants.GOVERNANCE_REGISTRY_BASE_PATH + RegistryConstants.PATH_SEPARATOR;
    private static final String BRANCHES = "branches";
    private static final String TESTING = "testing";
    private static final String PRODUCTION = "production";
    private static final String SERVICE_MEDIA_TYPE = "application/vnd.wso2-service+xml";
    private static final String PROMOTE = "Promote";
    private static final String WSDLS = "wsdls";
    private static String GOVERNANCE_TESTING_SERVICE_PATH = GOVERNANCE_PATH + BRANCHES + RegistryConstants.PATH_SEPARATOR + TESTING + RegistryConstants.PATH_SEPARATOR + "services" + RegistryConstants.PATH_SEPARATOR;
    private static String GOVERNANCE_PRODUCTION_SERVICE_PATH = GOVERNANCE_PATH + BRANCHES + RegistryConstants.PATH_SEPARATOR + PRODUCTION + RegistryConstants.PATH_SEPARATOR + "services" + RegistryConstants.PATH_SEPARATOR;
    private static String GOVERNANCE_TRUNK_SERVICE_PATH = GOVERNANCE_PATH + TRUNK + RegistryConstants.PATH_SEPARATOR + "services" + RegistryConstants.PATH_SEPARATOR;
    private static String GOVERNANCE_TESTING_WSDL_PATH = GOVERNANCE_PATH + BRANCHES + RegistryConstants.PATH_SEPARATOR + TESTING + RegistryConstants.PATH_SEPARATOR + WSDLS + RegistryConstants.PATH_SEPARATOR;
    private static String GOVERNANCE_PRODUCTION_WSDL_PATH = GOVERNANCE_PATH + BRANCHES + RegistryConstants.PATH_SEPARATOR + PRODUCTION + RegistryConstants.PATH_SEPARATOR + WSDLS + RegistryConstants.PATH_SEPARATOR;
    private static String GOVERNANCE_TRUNK_WSDL_PATH = GOVERNANCE_PATH + TRUNK + RegistryConstants.PATH_SEPARATOR + WSDLS + RegistryConstants.PATH_SEPARATOR;

    private List<String> states = new ArrayList<String>();

    private Map<String, List<CheckItemBean>> checkListItems = new HashMap<String, List<CheckItemBean>>();
    private Map<String, List<ValidationsBean>> transisionValidations = new HashMap<String, List<ValidationsBean>>();
    private Map<String, List<PermissionsBean>> transisionPermission = new HashMap<String, List<PermissionsBean>>();
    private Map<String, List<String>> stateEvents = new HashMap<String, List<String>>();
    private Map<String, List<ScriptBean>> scriptElements = new HashMap<String, List<ScriptBean>>();
//    private String currentLifeCycleExecutionState;

    private String stateProperty = "registry.lifecycle.SoftwareProjectLifecycle.state";
    private String lifecycleProperty = "registry.LC.name";
    boolean isConfigurationFromResource = false;
    private String configurationResourcePath = "";
    private OMElement configurationElement = null;
    private String aspectName = "";

    private SCXML scxml;
//    private SCXMLExecutor executor = null;


    public DefaultLifeCycle(OMElement config) throws RegistryException {

//        ugly code. Improve it
        String currentAspectName = config.getAttributeValue(new QName("name"));
        aspectName = currentAspectName;
        currentAspectName = currentAspectName.replaceAll("\\s", "");
        stateProperty = "registry.lifecycle." + currentAspectName + ".state";

//        executor = new SCXMLExecutor();
//        executor.setRootContext(new ELContext());
//        executor.setEvaluator(new ELEvaluator());

        Iterator stateElements = config.getChildElements();
        while (stateElements.hasNext()) {
            OMElement stateEl = (OMElement) stateElements.next();

            if (stateEl.getAttribute(new QName("type")) != null) {
                String type = stateEl.getAttributeValue(new QName("type"));
                if (type.equalsIgnoreCase("resource")) {
                    isConfigurationFromResource = true;
                    configurationResourcePath = RegistryUtils.getAbsolutePath(
                            RegistryContext.getBaseInstance(), stateEl.getText());
                    states.clear();
                    checkListItems.clear();
                    transisionPermission.clear();
                    transisionValidations.clear();

                    break;
                } else if (type.equalsIgnoreCase("literal")) {
                    isConfigurationFromResource = false;
                    configurationElement = stateEl.getFirstElement();
                    states.clear();
                    checkListItems.clear();
                    transisionPermission.clear();
                    transisionValidations.clear();

                    break;
                }
            }
            String name = stateEl.getAttributeValue(new QName("name"));
            if (name == null) {
                throw new IllegalArgumentException(
                        "Must have a name attribute for each state");
            }
            states.add(name);
        }
    }

    @Override
    public void associate(Resource resource, Registry registry)
            throws RegistryException {

        states.clear();
        try {
            setScxmlConfiguration(registry);
//            if (executor.getStateMachine() != null)
//                executor.reset();

            if (SERVICE_MEDIA_TYPE.equals(resource.getMediaType())) {
                List propertyValues = resource.getPropertyValues(lifecycleProperty);
                if (propertyValues != null && propertyValues.size() > 0) {
                    return;
                }
            }
            if (states.size() == 0) {
                populateItems();
            }
//            Creating the checklist
//            this is the first time the life cycle is associated with a resource.
            AddCheckItems(resource, checkListItems.get(scxml.getInitial()), scxml.getInitial());
            addScripts(scxml.getInitial(), resource);

        } catch (XMLStreamException e) {
            log.error(e);
        } catch (SAXException e) {
            log.error(e);
        } catch (ModelException e) {
            log.error(e);
        } catch (IOException e) {
            log.error(e);
        } catch (UserStoreException e) {
            log.error(e);
        } catch (Exception e) {
            throw new RegistryException("Resource does not contain a valid XML configuration: " + e.toString());
        }

//        currentLifeCycleExecutionState = scxml.getInitial();


        resource.setProperty(stateProperty, scxml.getInitial().replace(".", " "));
        resource.setProperty(lifecycleProperty, aspectName);

    }

    private void setScxmlConfiguration(Registry registry) throws RegistryException, XMLStreamException, IOException,
            SAXException, ModelException {
        String xmlContent = "";
        if (isConfigurationFromResource) {
            Resource configurationResource = registry.get(configurationResourcePath);
            xmlContent = new String((byte[]) configurationResource.getContent());
            configurationElement = AXIOMUtil.stringToOM(xmlContent);
        }

        OMElement scxmlElement = configurationElement.getFirstElement();
        scxml = SCXMLParser.parse(new InputSource(new CharArrayReader((scxmlElement.toString()).toCharArray())), null);
    }

    private void AddCheckItems(Resource resource, List<CheckItemBean> currentStateCheckItems, String state)
            throws UserStoreException {

        String[] roles = CurrentSession.getUserRealm().getUserStoreManager().getRoleListOfUser(CurrentSession.getUser());
        if (currentStateCheckItems != null && roles.length > 0) {
            int order = 0;
            for (CheckItemBean currentStateCheckItem : currentStateCheckItems) {
                List<PermissionsBean> permissions = currentStateCheckItem.getPermissionsBeans();

                List<String> items = new ArrayList<String>();
                items.add("status:" + state);
                items.add("name:" + currentStateCheckItem.getName());
                items.add("value:false");
                items.add("order:" + order);
                if (getActionPermission(roles, permissions) || permissions == null)
                    items.add("visible:true");
                else
                    items.add("visible:false");
                String resourcePropertyNameForItem = REGISTRY_CUSTOM_LIFECYCLE_CHECKLIST_OPTION +
                        ++order + ".item";
                resource.setProperty(resourcePropertyNameForItem, items);

            }
        }

    }

    private void addScripts(String state, Resource resource) {
        List<ScriptBean> scriptList = scriptElements.get(state);
        if (scriptList != null) {
            for (ScriptBean scriptBean : scriptList) {
                if (scriptBean.isConsole()) {
                    List<String> items = new ArrayList<String>();
                    items.add(scriptBean.getScript());
                    items.add(scriptBean.getFunctionName());
//                    items.add("eventName:" + scriptBean.getEventName());

                    String resourcePropertyNameForScript = REGISTRY_CUSTOM_LIFECYCLE_CHECKLIST_JS_SCRIPT_CONSOLE
                            + state + "." + scriptBean.getEventName();
                    resource.setProperty(resourcePropertyNameForScript, items);
                }
            }
        }
    }

    @Override
    public String[] getAvailableActions(RequestContext context) {
        try {
            if (states.size() == 0) {
                Registry registry = context.getRegistry();
                setScxmlConfiguration(registry);
                populateItems();
            }

        } catch (Exception e) {
            throw new RuntimeException("Resource does not contain a valid XML configuration: " + e.toString());
        }

        /*
* Need to check whether the correct user has done the checking*/

        ArrayList<String> actions = new ArrayList<String>();
        Resource resource = context.getResource();
        String user = CurrentSession.getUser();

        String currentState = resource.getProperty(stateProperty).replace(" ", ".");
        State currentExecutionState = (State) (scxml.getChildren()).get(currentState);
        List currentTransitions = currentExecutionState.getTransitionsList();

        try {
            List<PermissionsBean> permissionsBeans = transisionPermission.get(currentState);
            String[] roles = CurrentSession.getUserRealm().getUserStoreManager().getRoleListOfUser(user);

            /*In this loop we do both of the following tasks
            * 1.Make check items visible, not visible to the user
            * 2.Get the list of actions that is possible to the user*/

            //TODO improve logic if possible
            for (Object currentTransition : currentTransitions) {
                Transition t = (Transition) currentTransition;
                String transitionName = t.getEvent();

                Properties properties = resource.getProperties();
                List<String> propertyNames = new LinkedList<String>();
                for (Object o : properties.keySet()) {
                    String temp = o.toString();
                    if (temp.startsWith(REGISTRY_CUSTOM_LIFECYCLE_CHECKLIST_OPTION)) {
                        propertyNames.add(temp);
                    }
                }
                for (String propertyName : propertyNames) {
                    //sets the visibility of all to false;
                    List<String> propValueOld = resource.getPropertyValues(propertyName);
                    propValueOld.remove("visible:true");
                    propValueOld.add("visible:false");

                    Set set1 = new HashSet(propValueOld);
                    resource.removeProperty(propertyName);
                    resource.setProperty(propertyName, new ArrayList<String>(set1));


                    String propertyValue = properties.get(propertyName).toString();
                    List<CheckItemBean> currentStateCheckItems = checkListItems.get(currentState);
                    if (currentStateCheckItems != null && roles.length > 0) {
                        for (CheckItemBean currentStateCheckItem : currentStateCheckItems) {
                            List<PermissionsBean> permissions = currentStateCheckItem.getPermissionsBeans();
                            if (permissions == null || getActionPermission(roles, permissions)) {

//                                if (propertyValue.contains(currentStateCheckItem.getName()) &&
//                                        propertyValue.contains("visible:false")) {
                                if (propertyValue.contains(currentStateCheckItem.getName())) {
                                    List<String> propValue = resource.getPropertyValues(propertyName);
                                    propValue.remove("visible:false");
                                    propValue.add("visible:true");

                                    Set set2 = new HashSet(propValue);
                                    resource.removeProperty(propertyName);
                                    resource.setProperty(propertyName,new ArrayList<String>(set2));
                                    continue;
                                }
/*
                                else if (!propertyValue.contains(currentStateCheckItem.getName()) &&
                                        propertyValue.contains("visible:true")) {
                                    List<String> propValue = resource.getPropertyValues(propertyName);
                                    propValue.remove("visible:true");
                                    propValue.add("visible:false");
                                    resource.removeProperty(propertyName);
                                    resource.setProperty(propertyName, propValue);
                                }
*/
                            }
                        }

                    }
                }
                List<String> possibleActions = getPossibleActions(resource, currentState);
                if ((getTransitionPermission(roles, permissionsBeans, transitionName) || permissionsBeans == null)
                        && possibleActions.contains(transitionName)) {
                    actions.add(transitionName);
                }
            }
            if (CurrentSession.getUserRealm().getAuthorizationManager().isUserAuthorized(user, resource.getPath()
                    , ActionConstants.PUT))
                context.getRegistry().put(resource.getPath(), resource);
        } catch (UserStoreException e) {
            log.error("Failed to get the current user role :", e);
        } catch (RegistryException e) {
            log.error("Failed to put the resource to the registry :", e);
        }
        return actions.toArray(new String[actions.size()]);
    }

    private boolean getActionPermission(String[] roles, List<PermissionsBean> permissionsBeans) {
        Set permissionRoleSet = new HashSet(Arrays.asList(roles));
        if (permissionsBeans != null) {
            for (PermissionsBean permission : permissionsBeans) {
                if (permission.getRoles() != null) {
                    List premRoles = permission.getRoles();
                    permissionRoleSet.retainAll(premRoles);
                }
            }
        }

        return !permissionRoleSet.isEmpty();
    }

    private boolean getTransitionPermission(String[] roles, List<PermissionsBean> permissionsBeans, String eventName) {
        Set premSet = new HashSet(Arrays.asList(roles));
        if (permissionsBeans != null) {
            for (PermissionsBean permission : permissionsBeans) {
                if (permission.getForEvent().equals(eventName) && permission.getRoles() != null) {
                    List premRoles = permission.getRoles();
                    premSet.retainAll(premRoles);
                }
            }
        }
        return !premSet.isEmpty();
    }

    private boolean doAllCustomValidations(RequestContext context, String currentState) {
        //doing the check item validations
        List<CheckItemBean> currentStateCheckItems = checkListItems.get(currentState);
        for (CheckItemBean currentStateCheckItem : currentStateCheckItems) {
            if (!doCustomValidations(context, currentStateCheckItem.getValidationBeans())) {
                return false;
            }
        }
        //doing the transition validations
        if (!doCustomValidations(context, transisionValidations.get(currentState))) {
            return false;
        }

        return true;
    }

    private boolean doCustomValidations(RequestContext context, List<ValidationsBean> validationsBeans) {
        /*
       * This validations should include checkitems validations as well
       * */
        //TODO fix the checkitem validations
        if (validationsBeans != null) {
            for (ValidationsBean validationsBean : validationsBeans) {
                if (validationsBean.getClassName() != null && !validationsBean.getClassName().equals("")) {
                    try {
                        /*Class validationsClass = classLoader.loadClass(validationsBean.getClassName());
                        Object obj = validationsClass.newInstance();
                        CustomValidations customValidations = (CustomValidations) validationsClass.newInstance();
                        customValidations.init(validationsBean.getParamNameValues());*/

                        ClassLoader loader = Thread.currentThread().getContextClassLoader();
                        Class<?> validationsClass = Class.forName(validationsBean.getClassName(), true, loader);
                        CustomValidations customValidations = (CustomValidations) validationsClass.newInstance();
                        customValidations.init(validationsBean.getParamNameValues());

                        if (!customValidations.validate(context)) {
                            return false;
                        }

                    } catch (ClassNotFoundException e) {
                        log.error("Unable to load validations class", e);
                    } catch (InstantiationException e) {
                        log.error("Unable to load validations class", e);
                    } catch (IllegalAccessException e) {
                        log.error("Unable to load validations class", e);
                    }
                }
            }
        }

        return true;
    }

    @Override
    public void invoke(RequestContext context, String action) throws RegistryException {
        invoke(context,action,Collections.<String, String>emptyMap());
    }

    @Override
    public void invoke(RequestContext requestContext, String action,Map<String,String> parameterMap)
            throws RegistryException {
        Resource resource = requestContext.getResource();
        String currentState = resource.getProperty(stateProperty).replace(" ", ".");
        String resourcePath = requestContext.getResourcePath().getPath();
        String currentResourcePath = new String(resourcePath);
        boolean changed=false;
        boolean actionSuccessful=false;
        String nextState=currentState;

//        if (executor.getStateMachine() == null) {
//            executor.setStateMachine(scxml);
//
//            try {
//                executor.go();
//            } catch (ModelException e) {
//                log.error("Failed to start the scxml executor :", e);
//            }
//        }
        State currentExecutionState = (State) scxml.getChildren().get(currentState);
        Map<String,String> oldPathNewPathMap = new HashMap<String, String>();
        Resource newResource = requestContext.getRegistry().newResource();

//        Modify here for the checkitem and other validations.
        List transitions = currentExecutionState.getTransitionsList();
        try {
            String user = CurrentSession.getUser();
            String[] roles = CurrentSession.getUserRealm().getUserStoreManager().getRoleListOfUser(user);

            List<String> possibleEvents = getPossibleActions(resource, currentState);
            if (possibleEvents.size() > 0) {
                for (Object o : transitions) {
                    String eventName = ((Transition) o).getEvent();
                    if (possibleEvents.contains(eventName) && eventName.contains(action)) {
//                        TriggerEvent trigger = new TriggerEvent(eventName, TriggerEvent.CHANGE_EVENT);
                        nextState =((Transition) o).getNext();
                        try {
                            /*transition validations go here
              * There is need to check the transition permissions again as well to avoid fraud*/
                            if (getTransitionPermission(roles, transisionPermission.get(currentState), eventName)) {
                                if (doAllCustomValidations(requestContext, currentState)) {
//                                    Here we do the moving of the services and all the associated services
//                                    this is a temporary code segment and will be changed in the next release.

                                    if (SERVICE_MEDIA_TYPE.equals(resource.getMediaType()) && (resourcePath.startsWith(GOVERNANCE_PATH + TRUNK))
                                            ||(resourcePath.startsWith(GOVERNANCE_PATH+BRANCHES))) {

                                        if (action.equals(PROMOTE) && parameterMap != null) {
                                            for (Map.Entry<String, String> keyValueSet : parameterMap.entrySet()) {
                                                String path = keyValueSet.getKey();

                                                if (keyValueSet.getKey().contains(GOVERNANCE_PATH + TRUNK)) {
//                                                This method is only valid for resources. Not for collections
//                                                moving from trunk to branches/testing
                                                    path = path.replace(GOVERNANCE_PATH + TRUNK,
                                                            GOVERNANCE_PATH + BRANCHES + RegistryConstants.PATH_SEPARATOR + TESTING);
//                                                    executor.reset();

                                                } else if (keyValueSet.getKey().contains(GOVERNANCE_PATH + BRANCHES
                                                        + RegistryConstants.PATH_SEPARATOR + TESTING)) {
//                                                Moving from branches/testing to branches/production
                                                    path = path.replace(GOVERNANCE_PATH + BRANCHES
                                                            + RegistryConstants.PATH_SEPARATOR + TESTING,
                                                            GOVERNANCE_PATH + BRANCHES + RegistryConstants.PATH_SEPARATOR + PRODUCTION);
                                                }

                                                if (path.contains(GOVERNANCE_TESTING_SERVICE_PATH) || path.contains(GOVERNANCE_PRODUCTION_SERVICE_PATH)) {
                                                    if (path.contains(GOVERNANCE_PATH + BRANCHES + RegistryConstants.PATH_SEPARATOR + PRODUCTION)) {
                                                        path = path.substring(0, path.lastIndexOf(RegistryConstants.PATH_SEPARATOR));
                                                        path = path.substring(0, path.lastIndexOf(RegistryConstants.PATH_SEPARATOR));
                                                    }
                                                    resourcePath = path;
                                                    oldPathNewPathMap.put(keyValueSet.getKey(), CommonUtil.computeServicePathWithVersion(path, keyValueSet.getValue()));
                                                    String newContent = new String((byte[]) resource.getContent());
                                                    newResource.setContent(newContent.toString().getBytes());
                                                    continue;
                                                } else {

                                                    String pathPrefix = "";
                                                    if (path.contains(GOVERNANCE_PATH + BRANCHES + RegistryConstants.PATH_SEPARATOR + PRODUCTION)) {
                                                        pathPrefix = path.substring(0,path.lastIndexOf(RegistryConstants.PATH_SEPARATOR));
                                                    } else {
                                                        pathPrefix = path;
                                                    }
                                                    String pathSuffix = path.substring(path.lastIndexOf(RegistryConstants.PATH_SEPARATOR) + 1);
                                                    path = pathPrefix.substring(0, pathPrefix.lastIndexOf(RegistryConstants.PATH_SEPARATOR))
                                                            + RegistryConstants.PATH_SEPARATOR + keyValueSet.getValue()
                                                            + RegistryConstants.PATH_SEPARATOR + pathSuffix;
                                                    oldPathNewPathMap.put(keyValueSet.getKey(), path);

                                                }
                                                requestContext.getRegistry().copy(keyValueSet.getKey(), path);
                                            }

//                                        This loop is here because the 1st loop adds the resources with the new version and
//                                        after that we have to add the new dependencies.
                                            for (Map.Entry<String, String> keyValueSet : parameterMap.entrySet()) {
                                                if ((keyValueSet.getKey().contains(GOVERNANCE_TRUNK_SERVICE_PATH))||
                                                        (keyValueSet.getKey().contains(GOVERNANCE_TESTING_SERVICE_PATH))||
                                                        (keyValueSet.getKey().contains(GOVERNANCE_PRODUCTION_SERVICE_PATH))){
                                                    OMElement newContent = stringToOM(new String((byte[]) newResource.getContent()));
                                                    setServiceVersion(newContent, parameterMap.get(keyValueSet.getKey()));
                                                    newResource.setContent(newContent.toString().getBytes());
                                                }
                                                if ((keyValueSet.getKey().contains(GOVERNANCE_TRUNK_WSDL_PATH))||
                                                        (keyValueSet.getKey().contains(GOVERNANCE_TESTING_WSDL_PATH))||
                                                        (keyValueSet.getKey().contains(GOVERNANCE_PRODUCTION_WSDL_PATH))){
                                                    OMElement newContent = stringToOM(new String((byte[]) newResource.getContent()));
                                                    setWSDLURL(newContent, oldPathNewPathMap.get(keyValueSet.getKey()));
                                                    newResource.setContent(newContent.toString().getBytes());
//                                                    the above part is the modification of the service resource
                                                }

                                            }
                                            ServiceManager manager = new ServiceManager(requestContext.getSystemRegistry());
                                            XMLStreamReader reader = XMLInputFactory.newInstance()
                                                    .createXMLStreamReader(
                                                            new ByteArrayInputStream((byte[]) newResource.getContent()));
                                            StAXOMBuilder builder = new StAXOMBuilder(reader);
                                            OMElement serviceElement = builder.getDocumentElement();
                                            serviceElement.build();
                                            OMFactory fac = OMAbstractFactory.getOMFactory();
                                            //adding required fields at the top of the xml which will help to easily read in service side
                                            Iterator it = serviceElement.getChildrenWithLocalName("newServicePath");
                                            if (it.hasNext()) {
                                                while (it.hasNext()) {
                                                    OMElement next = (OMElement) it.next();
                                                    next.setText(resourcePath);
                                                    break;
                                                }
                                            } else {
                                                OMElement operation = fac.createOMElement("newServicePath", serviceElement.getNamespace(), serviceElement);
                                                operation.setText(resourcePath);
                                            }
//                                            this is here to override the default path
                                            serviceElement.build();
                                            newResource.setContent(new String(serviceElement.toString().getBytes()));
                                            newResource.setMediaType(org.wso2.carbon.registry.extensions.utils.CommonConstants.SERVICE_MEDIA_TYPE);
                                            Properties properties = new Properties(resource.getProperties());
                                            newResource.setProperties(properties);

                                            Service service = manager.newService(serviceElement);
                                            manager.addService(service);
                                            resourcePath = CommonUtil.computeServicePathWithVersion(resourcePath, parameterMap.get(currentResourcePath));
                                            changed = true;

                                        } else if (action.equals("Demote")) {
                                            return;
                                        }
                                    }
                                    actionSuccessful = true;
//                                    executor.triggerEvent(trigger);
                                    /*doing the transition scripting
                            * Here only the server side scripting are done*/

                                    List<ScriptBean> scriptElement = scriptElements.get(currentState);
                                    if (scriptElement != null) {
                                        for (ScriptBean scriptBean : scriptElement) {
                                            if (scriptBean.getEventName().equals(eventName) && !scriptBean.isConsole()) {
                                                executeJS(AXIOMUtil.stringToOM(scriptBean.getScript()).getText()
                                                        + "\n" + scriptBean.getFunctionName() + "()");
                                            }
                                        }
                                    }
                                    break;
                                } else {
                                    log.info("Transition validations failed.");
                                }
                            }
                        } catch (XMLStreamException e) {
                            log.error("JavaScript execution failed :", e);
                        } catch (GovernanceException e) {
                            e.printStackTrace()//To change body of catch statement use File | Settings | File Templates.
                        }
                    }
                }
            }
        } catch (UserStoreException e) {
            log.error("Failed to get the current user role :" + e.toString());
        }
//            if (!state.getId().equals(currentLifeCycleExecutionState)) {
//                currentLifeCycleExecutionState = state.getId();

        if (!currentState.equals(nextState) && actionSuccessful) {
            State state = (State) scxml.getChildren().get(nextState);
            if (changed) {
                requestContext.getSystemRegistry().put(resourcePath, newResource);
                requestContext.getSystemRegistry().associateAspect(oldPathNewPathMap.get(currentResourcePath), aspectName);
                newResource = requestContext.getSystemRegistry().get(resourcePath);
                newResource.setProperty(stateProperty, state.getId().replace(".", " "));
                try {
                    AddCheckItems(newResource, checkListItems.get(state.getId()), state.getId());
                    addScripts(state.getId(), newResource);
                } catch (UserStoreException e) {
                    log.error("Authentication exception", e);
                }
            } else {
                resource.setProperty(stateProperty, state.getId().replace(".", " "));
                try {
                    AddCheckItems(resource, checkListItems.get(state.getId()), state.getId());
                    addScripts(state.getId(), resource);
                } catch (UserStoreException e) {
                    log.error("Authentication exception", e);
                }
            }
        }
//        } else {
//            throw new RegistryException("Multiple states have been defined");
//        }
        if (changed) {
            requestContext.getSystemRegistry().put(resourcePath, newResource);
        } else {
            requestContext.getSystemRegistry().put(currentResourcePath, resource);
        }

/*
* The following scenarios can be present
*
* 1. type: dependency, sourcePath: new, desinationPath: old, remove: true
* 2. type: dependency, sourcePath: old, desinationPath: new, remove: true
* 3. type: dependency, sourcePath: old, desinationPath: old, remove: false
* 4. type: other, sourcePath: old, desinationPath: old, remove: false
* 5. type: other, sourcePath: new, desinationPath: old, remove: true
* 6. type: other, sourcePath: old, desinationPath: new, remove: true
* */
        for (Map.Entry<String, String> keyValueSet : parameterMap.entrySet()) {
            Association[] associations = requestContext.getRegistry().getAllAssociations(keyValueSet.getKey());
            for (Association association : associations) {
                if (association.getDestinationPath().equals(keyValueSet.getKey())) {
                    requestContext.getRegistry().removeAssociation(
                            association.getSourcePath(),
                            oldPathNewPathMap.get(association.getDestinationPath()),
                            association.getAssociationType());
                }
                if (association.getSourcePath().equals(keyValueSet.getKey())) {
                    requestContext.getRegistry().removeAssociation(
                            oldPathNewPathMap.get(association.getSourcePath()),
                            association.getDestinationPath(),
                            association.getAssociationType());

                }
                if(oldPathNewPathMap.containsKey(association.getDestinationPath())
                        && oldPathNewPathMap.containsKey(association.getSourcePath())){
                    requestContext.getRegistry().addAssociation(
                            oldPathNewPathMap.get(association.getSourcePath())
                            , oldPathNewPathMap.get(association.getDestinationPath())
                            , association.getAssociationType());
                }
            }
        }
    }

    private void populateItems() throws Exception {
        Map stateList = scxml.getChildren();

        for (Object stateObject : stateList.entrySet()) {

            Map.Entry state = (Map.Entry) stateObject;

            String currentStateName = (String) state.getKey();
            State currentState = (State) state.getValue();
            Datamodel model = currentState.getDatamodel();

            states.add(currentStateName);
            if (model != null) {
                List dataList = model.getData();
                for (Object dataObject : dataList) {
                    Data data = (Data) dataObject;
                    OMElement node = XMLUtils.toOM((Element) data.getNode());
                    //when associating we will map the custom datamodel to a set of beans. These will be used for further actions.
                    //adding the checkItems
                    if (!checkListItems.containsKey(currentStateName)
                            && (node.getAttributeValue(new QName("name")).equals("checkItems"))) {
                        List<CheckItemBean> items = new ArrayList<CheckItemBean>();
                        Iterator checkItemIterator = node.getChildElements();
                        while (checkItemIterator.hasNext()) {
                            CheckItemBean checkItemBean = new CheckItemBean();
                            OMElement childElement = (OMElement) checkItemIterator.next();

                            //setting the check item name
                            checkItemBean.setName(childElement.getAttributeValue(new QName("name")));

                            //setting the transactionList
                            if ((childElement.getAttributeValue(new QName("forEvent"))) != null) {
                                checkItemBean.setEvents(Arrays.asList((childElement
                                        .getAttributeValue(new QName("forEvent"))).split(",")));
                            }

                            Iterator permissionElementIterator = childElement
                                    .getChildrenWithName(new QName("permissions"));

                            while (permissionElementIterator.hasNext()) {
                                OMElement permissionElement = (OMElement) permissionElementIterator.next();

                                Iterator permissions = permissionElement.getChildElements();
                                List<PermissionsBean> premBeanList = new ArrayList<PermissionsBean>();

                                while (permissions.hasNext()) {
                                    OMElement premChild = (OMElement) permissions.next();
                                    premBeanList.add(createPermissionBean(premChild));
                                }
                                checkItemBean.setPermissionsBeans(premBeanList);
                            }

                            Iterator validationsElementIterator = childElement.getChildrenWithName(new QName("validations"));
                            while (validationsElementIterator.hasNext()) {
                                //setting the validation bean
                                OMElement validationElement = (OMElement) validationsElementIterator.next();
                                Iterator validations = validationElement.getChildElements();
                                List<ValidationsBean> validationsBeanList = new ArrayList<ValidationsBean>();
                                while (validations.hasNext()) {
                                    //this loop is to iterate the validation elements
                                    OMElement valiChild = (OMElement) validations.next();
                                    validationsBeanList.add(createValidationsBean(valiChild));
                                }
                                checkItemBean.setValidationBeans(validationsBeanList);
                            }
                            items.add(checkItemBean);
                        }
                        if (items.size() > 0) {
                            checkListItems.put(currentStateName, items);
                        }
                    }

                    //                  Adding the state validations
                    if (!transisionValidations.containsKey(currentStateName)
                            && (node.getAttributeValue(new QName("name")).equals("transitionValidation"))) {
                        List<ValidationsBean> validationsBeanList = new ArrayList<ValidationsBean>();
                        Iterator validationsIterator = node.getChildElements();
                        while (validationsIterator.hasNext()) {
                            OMElement valiChilds = (OMElement) validationsIterator.next();
                            validationsBeanList.add(createValidationsBean(valiChilds));
                        }
                        transisionValidations.put(currentStateName, validationsBeanList);
                    }
//                    adding the transition permissions
                    if (!transisionPermission.containsKey(currentStateName)
                            && (node.getAttributeValue(new QName("name")).equals("transitionPermission"))) {
                        List<PermissionsBean> permissionsBeanList = new ArrayList<PermissionsBean>();
                        Iterator permissionIterator = node.getChildElements();
                        while (permissionIterator.hasNext()) {
                            OMElement premChilds = (OMElement) permissionIterator.next();
                            permissionsBeanList.add(createPermissionBean(premChilds));
                        }
                        transisionPermission.put(currentStateName, permissionsBeanList);
                    }
//                    adding the script elements
                    if (!scriptElements.containsKey(currentStateName)
                            && (node.getAttributeValue(new QName("name")).equals("transitionScripts"))) {
                        List<ScriptBean> scriptBeans = new ArrayList<ScriptBean>();
                        Iterator scriptIterator = node.getChildElements();

                        while (scriptIterator.hasNext()) {
                            OMElement script = (OMElement) scriptIterator.next();
                            Iterator scriptChildIterator = script.getChildElements();
                            while (scriptChildIterator.hasNext()) {
                                OMElement scriptChild = (OMElement) scriptChildIterator.next();
                                scriptBeans.add(new ScriptBean(scriptChild.getQName().getLocalPart().equals("console"),
                                        scriptChild.getAttributeValue(new QName("function")),
                                        script.getAttributeValue(new QName("forEvent")),
                                        scriptChild.getFirstElement().toString()));
                            }
                        }
                        scriptElements.put(currentStateName, scriptBeans);

                    }
                }
            }
            List<String> events = new ArrayList<String>();
            for (Object t : currentState.getTransitionsList()) {
                Transition transition = (Transition) t;
                events.add(transition.getEvent());
            }
            stateEvents.put(currentStateName, events);
        }
    }


    private PermissionsBean createPermissionBean(OMElement premChild) {
        PermissionsBean premBean = new PermissionsBean();
        premBean.setForEvent(premChild.getAttributeValue(new QName("forEvent")));
        if (premChild.getAttributeValue(new QName("roles")) != null)
            premBean.setRoles(Arrays.asList(premChild.getAttributeValue(new QName("roles"))
                    .split(",")));
        return premBean;
    }

    private ValidationsBean createValidationsBean(OMElement valiChild) {
        ValidationsBean validationsBean = new ValidationsBean();
        Map<String, String> paramNameValues = new HashMap<String, String>();

        Iterator parameters = valiChild.getChildElements();
        while (parameters.hasNext()) {
            // this loop is for the parameter name and values
            OMElement paramChild = (OMElement) parameters.next();
            paramNameValues.put(paramChild.getAttributeValue(new QName("name")),
                    paramChild.getAttributeValue(new QName("value")));
        }
        validationsBean.setParamNameValues(paramNameValues);
        validationsBean.setClassName(valiChild.getAttributeValue(new QName("class")));
        validationsBean.setEventName(valiChild.getAttributeValue(new QName("event")));
        return validationsBean;
    }

    private List<String> getPossibleActions(Resource resource, String currentState) {

        Properties propertyNameValues = resource.getProperties();
        Iterator propIterator = propertyNameValues.entrySet().iterator();
        List<CheckItemBean> checkItems = checkListItems.get(currentState);
        List<String> events = new ArrayList<String>(stateEvents.get(currentState));

        if (checkItems !=null && checkItems.size()>0) {
            while (propIterator.hasNext()) {
                Map.Entry entry = (Map.Entry) propIterator.next();
                String propertyName = (String) entry.getKey();

                if (propertyName.startsWith(REGISTRY_CUSTOM_LIFECYCLE_CHECKLIST_OPTION)) {
                    List<String> propValues = (List<String>) entry.getValue();
                    for (String propValue : propValues)
                        if (propValue.startsWith("name:"))
                            for (CheckItemBean checkItem : checkItems)
                                if ((checkItem.getName().equals(propValue.substring(propValue.indexOf(":") + 1))) &&
                                        (checkItem.getEvents() != null) && propValues.contains("value:false")) {
                                    events.removeAll(checkItem.getEvents());
                                }
                }

            }
        }else{
            return Collections.emptyList();
        }
        return events;
    }

    private void executeJS(String script) {
        Context cx = Context.enter();
        try {
            ConfigurationContext configurationContext =
                    MessageContext.getCurrentMessageContext().getConfigurationContext();
            cx.putThreadLocal(MashupConstants.AXIS2_CONFIGURATION_CONTEXT, configurationContext);
            AxisService service = new AxisService();
            service.addParameter(MashupConstants.MASHUP_AUTHOR, CurrentSession.getUser());
            cx.putThreadLocal(MashupConstants.AXIS2_SERVICE, service);
            Scriptable scope = cx.initStandardObjects();
            ScriptableObject.defineClass(scope, ResourceHostObject.class);
            ScriptableObject.defineClass(scope, CollectionHostObject.class);
            ScriptableObject.defineClass(scope, RegistryHostObject.class);
            Object result = cx.evaluateString(scope, script, "<cmd>", 1, null);
            if (result != null && log.isInfoEnabled()) {
                log.info("JavaScript Result: " + Context.toString(result));
            }
        } catch (IllegalAccessException e) {
            log.error("Unable to defining registry host objects.", e);
        } catch (InstantiationException e) {
            log.error("Unable to instantiate the given registry host object.", e);
        } catch (InvocationTargetException e) {
            log.error("An exception occurred while creating registry host objects.", e);
        } catch (AxisFault e) {
            log.error("Failed to set user name parameter.", e);
        } catch (SecurityException ignored) {
            // If there is a security issue, simply live with that. This portion of the sample is
            // not intended to work on a system with security restrictions.
        } finally {
            Context.exit();
        }
    }


    @Override
    public void dissociate(RequestContext requestContext) {

        Resource resource = requestContext.getResource();

        if (resource != null) {
            resource.removeProperty(stateProperty);
            resource.removeProperty(lifecycleProperty);
        }
    }

    public boolean isValidRegistryCollection(String path) {
        if (!path.startsWith("/")) {
            return false;
        } else if (path.contains("~!@#$%^*()+={}[]|\\<>")) {
            return false;
        }
        return true;
    }

}
TOP

Related Classes of org.wso2.carbon.governance.registry.extensions.aspects.DefaultLifeCycle

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.