/*
* 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;
}
}