package org.gcube.portlets.admin.vredefinition.server; import java.io.Serializable; import java.rmi.RemoteException; import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import org.gcube.application.framework.core.session.ASLSession; import org.gcube.application.framework.core.session.SessionManager; import org.gcube.application.framework.vremanagement.vremanagement.impl.VREGeneratorEvo; import org.gcube.applicationsupportlayer.social.ApplicationNotificationsManager; import org.gcube.applicationsupportlayer.social.NotificationsManager; import org.gcube.applicationsupportlayer.social.shared.SocialNetworkingSite; import org.gcube.applicationsupportlayer.social.shared.SocialNetworkingUser; import org.gcube.common.homelibrary.home.HomeLibrary; import org.gcube.common.homelibrary.home.workspace.Workspace; import org.gcube.portal.custom.scopemanager.scopehelper.ScopeHelper; import org.gcube.portlets.admin.vredefinition.client.VREDefinitionService; import org.gcube.portlets.admin.vredefinition.shared.Functionality; import org.gcube.portlets.admin.vredefinition.shared.Resource; import org.gcube.portlets.admin.vredefinition.shared.ResourceCategory; import org.gcube.portlets.admin.vredefinition.shared.VREDescriptionBean; import org.gcube.portlets.admin.vredefinition.shared.exception.VREDefinitionException; import org.gcube.vomanagement.usermanagement.RoleManager; import org.gcube.vomanagement.usermanagement.UserManager; import org.gcube.vomanagement.usermanagement.impl.LiferayRoleManager; import org.gcube.vomanagement.usermanagement.impl.LiferayUserManager; import org.gcube.vomanagement.usermanagement.model.GCubeUser; import org.gcube.vremanagement.vremodel.cl.stubs.types.FunctionalityItem; import org.gcube.vremanagement.vremodel.cl.stubs.types.ResourceDescriptionItem; import org.gcube.vremanagement.vremodel.cl.stubs.types.ResourceItem; import org.gcube.vremanagement.vremodel.cl.stubs.types.SelectedResourceDescriptionType; import org.gcube.vremanagement.vremodel.cl.stubs.types.VREDescription; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.gwt.user.server.rpc.RemoteServiceServlet; import com.liferay.portal.service.UserLocalServiceUtil; /** * The VREDefinitionServiceImpl class. * @author Costantino Perciante at ISTI-CNR * (costantino.perciante@isti.cnr.it) */ public class VREDefinitionServiceImpl extends RemoteServiceServlet implements VREDefinitionService{ private static final long serialVersionUID = -7581858549584810224L; // Logger private static final Logger logger = LoggerFactory.getLogger(VREDefinitionServiceImpl.class); // some usefull constants private static final String DESIGNER = "Designer"; private static final String MANAGER = "Manager"; private static final String DESCRIPTION = "DESCRIPTION"; private static final String VRE_MANAGER_STRING = "VRE-Manager"; private static final String VRE_DEFINER_GENERATOR_ATTRIBUTE = "VREDefinerGenerator"; private static final String VRE_GENERATOR_ATTRIBUTE = "VREGenerator"; private static final String REEDIT_TYPE_ATTRIBUTE = "reeditType"; private static final String EDIT_MODE = "edit"; private static final String APPROVE_MODE = "approve"; private static final String VRE_NAME_FIELD = "vreName"; private static final String VRE_MANAGER_FIELD = "vreManager"; private static final String VRE_DESIGNER_FIELD = "vreDesigner"; private static final String VRE_DESCRIPTION_FIELD = "vreDescription"; private static final String VRE_START_TIME_FIELD = "vreStartTime"; private static final String VRE_END_TIME_FIELD = "vreEndTime"; //dev user public static final String defaultUserId = "test.user"; //dev vo private static final String voID = "/gcube/devsec"; @Override public void init() { logger.debug("Servlet init"); } @Override public void destroy(){ logger.debug("Servlet destroyed"); } /** * the current ASLSession * @return the session */ private ASLSession getASLSession() { String sessionID = this.getThreadLocalRequest().getSession().getId(); String user = (String) this.getThreadLocalRequest().getSession().getAttribute(ScopeHelper.USERNAME_ATTRIBUTE); if (user == null) { logger.warn("USER IS NULL setting " + defaultUserId + " and Running OUTSIDE PORTAL"); user = getDevelopmentUser(); SessionManager.getInstance().getASLSession(sessionID, user).setScope(voID); SessionManager.getInstance().getASLSession(sessionID, user).setAttribute(REEDIT_TYPE_ATTRIBUTE, APPROVE_MODE); } return SessionManager.getInstance().getASLSession(sessionID, user); } /** * Online or in development mode? * @return true if you're running into the portal, false if in development */ private boolean isWithinPortal() { try { UserLocalServiceUtil.getService(); return true; } catch (com.liferay.portal.kernel.bean.BeanLocatorException ex) { logger.trace("Development Mode ON"); return false; } } /** * when packaging test will fail if the user is not set to test.user * @return . */ public String getDevelopmentUser() { String user = defaultUserId; // user = "costantino.perciante"; return user; } /** * When the portlet starts, this method is invoked in order to return * 1) vre managers for the current VO * 2) the current designer (that is the current user) * 3) a VREDefinitionBean that will be filled somehow by the designer */ public Map getVRE() { logger.debug("########### INVOKED getVRE() METHOD ###########"); Map toReturn = new HashMap(); // retrieve the session ASLSession session = getASLSession(); // username String username = session.getUsername(); // check if development mode or portal if(!isWithinPortal()){ logger.debug("You are in dev mode"); return getFakeVreDefinition(); }else{ // check if we are in edit mode or not boolean editMode = isEditMode(); logger.debug("EDIT MODE IS " + editMode); // put this information in the returned hashmap toReturn.put(EDIT_MODE, editMode); try{ // user and role managers UserManager um = new LiferayUserManager(); RoleManager rm = new LiferayRoleManager(); // current org id of the vo long voOrgID = getASLSession().getGroupId(); long roleId = rm.getRoleId(VRE_MANAGER_STRING, getASLSession().getGroupId()); logger.debug(VRE_MANAGER_STRING + " has role id " + roleId + " into organization " + voOrgID); logger.debug("Trying to get roleid of " + VRE_MANAGER_STRING + " into " + getASLSession().getGroupName()); List belongingUsers = um.listUsersByGroupAndRole(voOrgID, roleId); logger.debug("Number of managers is " + belongingUsers.size()); ArrayList managers = new ArrayList(); for (int i = 0; i < belongingUsers.size(); i++) { managers.add(belongingUsers.get(i).getFullname()+" ("+belongingUsers.get(i).getUsername()+")"); } toReturn.put(MANAGER, managers); logger.debug("Managers set as " + managers); // set the designer String fullName = um.getUserByUsername(username).getFullname(); toReturn.put(DESIGNER, fullName+" ("+username+")"); logger.debug("Designer set as " + fullName+" ("+username+")"); // in edit mode we need to retrieve the selected manager as well as other vre info if(editMode){ try{ VREDescriptionBean vreBean = getVREInSession(); if(vreBean != null) { toReturn.put(VRE_NAME_FIELD,vreBean.getName()); toReturn.put(VRE_MANAGER_FIELD, vreBean.getManager()); toReturn.put(VRE_DESIGNER_FIELD, fullName+" ("+vreBean.getDesigner()+")"); // should be equal to DESIGNER toReturn.put(VRE_DESCRIPTION_FIELD, vreBean.getDescription()); toReturn.put(VRE_START_TIME_FIELD, vreBean.getStartTime()); toReturn.put(VRE_END_TIME_FIELD, vreBean.getEndTime()); } }catch(Exception e){ logger.error("Error while retrieving vre description bean", e); } } }catch(Exception e){ logger.error("Error while retrieving vre information", e); } } return toReturn; } /** * Generate random data * @return */ private Map getFakeVreDefinition() { Map toReturn = new HashMap(); ArrayList managers = new ArrayList(); managers.add("Pasquale Pagano (pasquale.pagano)"); managers.add("Andrea Manzi (andrea.manzi)"); managers.add("Massimiliano Assante (massimiliano.assante)"); toReturn.put(MANAGER, managers); // designer toReturn.put(DESIGNER, "Leonardo Candela (leonardo.candela)"); // check if we are in edit mode or not boolean editMode = isEditMode(); // put this information in the returned hashmap toReturn.put(EDIT_MODE, editMode); if(editMode){ try { VREDescriptionBean vreBean = getVREInSession(); if(vreBean != null) { logger.debug(" ########### VRE != NULL ##########"); logger.debug("Bean is " + vreBean); toReturn.put(VRE_NAME_FIELD,vreBean.getName()); toReturn.put(VRE_MANAGER_FIELD, vreBean.getManager()); toReturn.put(VRE_DESIGNER_FIELD, vreBean.getDesigner()); toReturn.put(VRE_DESCRIPTION_FIELD, vreBean.getDescription()); toReturn.put(VRE_START_TIME_FIELD, vreBean.getStartTime().getTime()); toReturn.put(VRE_END_TIME_FIELD, vreBean.getEndTime().getTime()); } } catch (Exception e1){ logger.error("Missing definition bean..."); } } return toReturn; } /** * Retrieve the VREDescriptionBean from the session if possible * @return * @throws VREDefinitionException */ private VREDescriptionBean getVREInSession() throws VREDefinitionException { VREGeneratorEvo vreGenerator = getVREGenerator(); VREDescriptionBean vreDescBean = null; try { VREDescription sd = vreGenerator.getVREModel(); vreDescBean = new VREDescriptionBean(sd.name(), sd.description(), sd.designer(), sd.manager(), sd.startTime().getTime(), sd.endTime().getTime()); } catch (RemoteException e) { throw new VREDefinitionException("Fail retrieve VRE"); } logger.debug("Model retrieved is " + vreDescBean); return vreDescBean; } /** * The VREGenerator is needed to retrieve VRE Bean information * @return */ private VREGeneratorEvo getVREGenerator(){ ASLSession d4ScienceSession = getASLSession(); VREGeneratorEvo vreGenerator = (VREGeneratorEvo) d4ScienceSession.getAttribute(VRE_DEFINER_GENERATOR_ATTRIBUTE); // if there is not..add it if(vreGenerator == null){ logger.debug("There is no VREGeneratorEvo in the session, adding it.."); vreGenerator = new VREGeneratorEvo(d4ScienceSession); d4ScienceSession.setAttribute(VRE_DEFINER_GENERATOR_ATTRIBUTE, vreGenerator); } return vreGenerator; } /** * Check if we are in edit mode or not * @return */ private boolean isEditMode(){ logger.debug("Checking if we are in edit mode..."); // retrieve current session ASLSession session = getASLSession(); // get this attribute String reeditType = (String)session.getAttribute(REEDIT_TYPE_ATTRIBUTE); // set to null the VRE_DEFINER_GENERATOR_ATTRIBUTE session.setAttribute(VRE_DEFINER_GENERATOR_ATTRIBUTE, null); // if the reeditType is actually edit if(reeditType != null && reeditType.equals(EDIT_MODE)) { // retrieve the vreid (of the vre to be changed) String vreid = (String) session.getAttribute(VRE_GENERATOR_ATTRIBUTE); if(vreid != null){ // put the generator in session VREGeneratorEvo vreGenerator = new VREGeneratorEvo(session, vreid); session.setAttribute(VRE_DEFINER_GENERATOR_ATTRIBUTE, vreGenerator); } // set to null the attribute REEDIT_TYPE_ATTRIBUTE session.setAttribute(REEDIT_TYPE_ATTRIBUTE, null); return true; } return false; } /** * {@inheritDoc} */ public ArrayList getFunctionality(boolean isEdit) throws VREDefinitionException { /* * if i am creating a new Vre I need to 'pretend' I already set the description to the service otherwise VREModeler won't return me the collections * if is editing instead this is not necessary */ if (!isEdit) { Calendar cal= Calendar.getInstance(); long startTime = cal.getTimeInMillis(); cal.add(Calendar.MONTH, 5); cal.add(Calendar.HOUR, 7); long endTime = cal.getTimeInMillis(); try { //a useless setVREModel() is needed to retrieve functionalities.... getVREGenerator().setVREModel("notCompletedVirtualResearchEnv.", UUID.randomUUID().toString(), UUID.randomUUID().toString(), UUID.randomUUID().toString(), startTime, endTime); Thread.sleep(1000); // wait a sec } catch (Exception e) { logger.error("Error on setVREModel()", e); } } // if the service is not ready, return null if (!getVREGenerator().isVreModelerServiceUp()) return null; // build up the list of functionalities List toReturn = new ArrayList(); try{ // get the list of main functionalities List listMainFunctionalities = getVREGenerator().getFunctionality(); if(listMainFunctionalities != null && !listMainFunctionalities.isEmpty()){ // for each functionality for (FunctionalityItem functionalityItem : listMainFunctionalities) { logger.debug("Reading FunctionalityItem with id:" + functionalityItem.id() + " and name " + functionalityItem.name()); // add it to the returning list Functionality mainFunctionality = new Functionality(functionalityItem.id(), functionalityItem.name(), functionalityItem.description(), functionalityItem.selected()); toReturn.add(mainFunctionality); // scan its children (if any) if(functionalityItem.children() == null || functionalityItem.children().isEmpty()){ logger.debug(functionalityItem.name() + " has no children."); } else{ // get its children List childrenFunctionalities = functionalityItem.children(); // subfunctionalities of our model List subFunctionalities = new ArrayList(); // for each subfunctionality for(FunctionalityItem childFunctionality: childrenFunctionalities){ logger.debug("Reading child FunctionalityItem " + childFunctionality.name() + " of node " + functionalityItem.name()); Functionality subFunctionality = new Functionality(childFunctionality.id(), childFunctionality.name(), childFunctionality.description(), childFunctionality.selected()); // this subfunctionality could have resource categories List resourcesDescriptionItems = childFunctionality.selectableResourcesDescription(); if(resourcesDescriptionItems != null && !resourcesDescriptionItems.isEmpty()){ // categories of our model List categories = new ArrayList(); for (ResourceDescriptionItem resourceDescriptionItem : resourcesDescriptionItems) { logger.debug("Reading ResourceDescriptionItem " + resourceDescriptionItem.description() + " of functionality " + childFunctionality.name()); // resource category list List resourceItems = resourceDescriptionItem.resources(); if(resourceItems != null && !resourceItems.isEmpty()){ ResourceCategory rc = new ResourceCategory(resourceDescriptionItem.id(), resourceDescriptionItem.description()); List resourceModels = new ArrayList(); for (ResourceItem resource : resourceDescriptionItem.resources()) { logger.debug("Reading resource " + resource.name() + " of ResourceDescriptionItem " + resourceDescriptionItem.description()); resourceModels.add(new Resource(resource.id(), resource.name(), resource.description(), resource.selected())); } // set resources for this category rc.setItems((ArrayList) resourceModels); // append the resource category to categories categories.add(rc); } } // append this resources to the child functionality subFunctionality.setResources(categories); } // add this subfunctionality to our functionality list subFunctionalities.add(subFunctionality); } // add the subfunctionalities to the main functionality mainFunctionality.setSubFunctionalities(subFunctionalities); } } } }catch(Exception e){ logger.error("Error while retrieving the list of functionalities", e); return null; } // return the list of functionalities return (ArrayList)toReturn; } /** * Set the vre functionalities and resources it will use. * @param functionalities * @return true on success, false otherwise */ private boolean setFunctionalities(List functionalities){ //filling up ArrayList toSend = new ArrayList(); // we need a list of checked subfunctionalities' ids ArrayList subfunctionalitiesIDS = new ArrayList(); // iterate over the macro functionalities for(Functionality macroFunctionality : functionalities){ logger.debug("Scanning macro functionality " + macroFunctionality.getName()); // retrieve its direct children List subfunctionalities = macroFunctionality.getSubFunctionalities(); // iterate for (Functionality subfunctionality : subfunctionalities) { logger.debug("Scanning sub functionality " + subfunctionality.getName()); if(subfunctionality.isSelected()){ logger.debug("This subfunctionality was selected"); // save its id subfunctionalitiesIDS.add(subfunctionality.getId()); // retrieve its children list List categories = subfunctionality.getResources(); if(categories != null){ for(ResourceCategory category : categories){ // get the description id String descriptionId = category.getId(); // get its resources ArrayList resources = category.getItems(); // list of ids for resources ArrayList resourceIds = new ArrayList(); if(resources != null){ logger.debug("Scanning resources of " + subfunctionality.getName()); for (Resource resource : resources) { if(resource.isSelected()){ logger.debug("Resource of " + resource.getName() + " was selected by the user"); // add its id resourceIds.add(resource.getId()); } } } SelectedResourceDescriptionType toAdd = new SelectedResourceDescriptionType(); toAdd.descriptionId(descriptionId); toAdd.resourceIds(resourceIds); toSend.add(toAdd); } } } } } // convert to array Integer funcIdAsInts[] = subfunctionalitiesIDS.toArray(new Integer[subfunctionalitiesIDS.size()]); // convert to array SelectedResourceDescriptionType[] selres = toSend.toArray(new SelectedResourceDescriptionType[toSend.size()]); logger.debug("SelectedResourceDescriptionType[] Sending to Service .... toSend size = " + toSend.size()); for (int i = 0; i < selres.length; i++) { logger.debug("SelectedResourceDescriptionType DESC: " + selres[i].getDescriptionId()); for (int j = 0; j < selres[i].resourceIds().size(); j++) { logger.debug("resid= " +selres[i].resourceIds().get(j)); } } // save the above information VREGeneratorEvo vreGenerator = getVREGenerator(); try { vreGenerator.setFunctionality(funcIdAsInts, selres); vreGenerator.setVREtoPendingState(); return true; } catch (RemoteException e) { logger.error("An error arises", e); return false; } } /** * {@inheritDoc} */ public boolean setVRE(VREDescriptionBean bean, ArrayList functionalities) throws VREDefinitionException { // retrieve information from the description bean String completeDesigner = bean.getDesigner(); bean.setDesigner(extractUserName(completeDesigner)); String managerUserName = extractUserName(bean.getManager()); bean.setManager(managerUserName); // set this description bean setVREDescription(bean); // save this functionalities setFunctionalities(functionalities); try { getVREGenerator().setVREtoPendingState(); getASLSession().setAttribute(VRE_DEFINER_GENERATOR_ATTRIBUTE, null); Workspace workspace = HomeLibrary.getUserWorkspace(getASLSession().getUsername()); ArrayList toSend = new ArrayList(); toSend.add(managerUserName); String subject = "New VRE Definition requires your approval"; String body = "Dear Manager, \n\n" + completeDesigner + " has created a VRE Definition indicating you as VRE Manager on " + getASLSession().getScope(); body+=".\n\nThe VRE Name is: " + bean.getName() +", the VRE Description is: " + bean.getDescription()+"."; String messagedId = workspace.getWorkspaceMessageManager().sendMessageToPortalLogins(subject, body, new ArrayList(), toSend); ASLSession session = getASLSession(); SocialNetworkingUser user = new SocialNetworkingUser(session.getUsername(), session.getUserEmailAddress(), session.getUserFullName(), session.getUserAvatarId()); NotificationsManager nnm = new ApplicationNotificationsManager(new SocialNetworkingSite(getThreadLocalRequest()), session.getScope(), user); if (nnm.notifyMessageReceived(managerUserName, messagedId, subject, body)) logger.trace("Sending VRE Definition create notification: " + subject + " OK"); return true; } catch (Exception e) { logger.error("Error while creating the new VRE ", e); } return false; } /** * Set the bean within the session * @param bean * @return * @throws VREDefinitionException */ private String setVREDescription(VREDescriptionBean bean) throws VREDefinitionException { VREGeneratorEvo vreGenerator = getVREGenerator(); ASLSession d4ScienceSession = getASLSession(); d4ScienceSession.setAttribute(VRE_NAME_FIELD, bean.getName()); d4ScienceSession.setAttribute(DESCRIPTION, bean.getDescription()); d4ScienceSession.setAttribute(DESIGNER, bean.getDesigner()); d4ScienceSession.setAttribute(MANAGER, bean.getManager()); try { vreGenerator.setVREModel(bean.getName(), bean.getDescription(), bean.getDesigner(), bean.getManager(), bean.getStartTime().getTime() , bean.getEndTime().getTime()); } catch (RemoteException e) { logger.error("An error arises", e); throw new VREDefinitionException("Set Description Error"); } return null; } /** * The original format looks like Clark Kent (clark.kent) and we need the name within brackets * @param toExtract * @return */ private String extractUserName(String toExtract) { int openBracket = toExtract.indexOf("(")+1; int closeBracket = toExtract.indexOf(")"); String toReturn = toExtract.substring(openBracket, closeBracket); logger.debug("Extracted username is " + toReturn); return toReturn; } }