package org.flowerplatform.codesync.remote; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.flowerplatform.common.util.Pair; import org.flowerplatform.communication.channel.CommunicationChannel; import org.flowerplatform.communication.stateful_service.StatefulServiceInvocationContext; import org.flowerplatform.communication.tree.GenericTreeContext; import org.flowerplatform.communication.tree.remote.GenericTreeStatefulService; import org.flowerplatform.communication.tree.remote.PathFragment; import org.flowerplatform.communication.tree.remote.TreeNode; import org.flowerplatform.editor.EditorPlugin; import org.flowerplatform.editor.model.remote.DiagramEditableResource; import org.flowerplatform.editor.model.remote.DiagramEditorStatefulService; import com.crispico.flower.mp.codesync.base.CodeSyncPlugin; import com.crispico.flower.mp.model.codesync.CodeSyncElement; /** * @author Cristina Constatinescu */ public class LocationForNewElementsStatefulService extends GenericTreeStatefulService { public static final String DIAGRAM_EDITABLE_RESOURCE_PATH_KEY = "diagramEditableResourcePath"; public static final String NEW_ELEMENTS_PATH_KEY = "newElementsPath"; public static final String ADDITIONAL_PATH_KEY = "additionalPath"; public static final String PATHS_TO_OPEN_KEY = "pathsToOpen"; @Override public String getStatefulClientPrefixId() { return "locationForNewElementsTreeId"; } private DiagramEditorStatefulService getDiagramEditorStatefulService() { return (DiagramEditorStatefulService) EditorPlugin.getInstance().getEditorStatefulServiceByEditorName("diagram"); } @Override public void openNode(StatefulServiceInvocationContext context, List<PathFragment> path, Map<Object, Object> clientContext) { super.openNode(context, path, clientContext); invokeClientMethod( context.getCommunicationChannel(), context.getStatefulClientId(), "setAdditionalInfo", new Object[] {clientContext.get(PATHS_TO_OPEN_KEY)}); } @Override public TreeNode openNodeInternal(CommunicationChannel channel, String statefulClientId, List<PathFragment> fullPath, Map<Object, Object> context) { TreeNode node = super.openNodeInternal(channel, statefulClientId, fullPath, context); String newElementsPath = (String) context.get(NEW_ELEMENTS_PATH_KEY); if (newElementsPath != null) { String[] tokens = newElementsPath.split("/"); int i = 0; TreeNode startNode = node; List<List<PathFragment>> pathsToOpen = new ArrayList<List<PathFragment>>(); while (i < tokens.length) { TreeNode tokenNode = pathFragmentExistsInTreeNode(startNode, new PathFragment(tokens[i], CodeSyncPlugin.FOLDER)); if (tokenNode != null) { List<PathFragment> path = new ArrayList<PathFragment>(); computePathForNode(tokenNode, path); pathsToOpen.add(path); startNode = tokenNode; } i++; } context.put(PATHS_TO_OPEN_KEY, pathsToOpen); } return node; } private void computePathForNode(TreeNode node, List<PathFragment> path) { if (node.getPathFragment() != null) { path.add(0, node.getPathFragment()); } if (node.getParent() != null) { computePathForNode(node.getParent(), path); } } private TreeNode pathFragmentExistsInTreeNode(TreeNode node, PathFragment pathFragment) { if (node.getPathFragment() != null && node.getPathFragment().equals(pathFragment)) { return node; } for (TreeNode child : node.getChildren()) { if (pathFragmentExistsInTreeNode(child, pathFragment) != null) { return child; } } return null; } @Override public Collection<Pair<Object, String>> getChildrenForNode(Object node, TreeNode treeNode, GenericTreeContext context) { String diagramEditableResourcePath = (String) context.getClientContext().get(DIAGRAM_EDITABLE_RESOURCE_PATH_KEY); if (node instanceof Class) { DiagramEditableResource der = (DiagramEditableResource) getDiagramEditorStatefulService().getEditableResource(diagramEditableResourcePath); ResourceSet resourceSet = der.getResourceSet(); Object project = CodeSyncPlugin.getInstance().getProjectAccessController().getContainingProjectForFile(der.getFile()); Resource codeSyncMappingResource = CodeSyncPlugin.getInstance().getCodeSyncMapping(project, resourceSet); List<Pair<Object, String>> result = new ArrayList<Pair<Object, String>>(); for (EObject eObject : codeSyncMappingResource.getContents()) { String type = ((CodeSyncElement) eObject).getType(); if (type.equals(CodeSyncPlugin.FOLDER)) { Pair<Object, String> pair = new Pair<Object, String>(eObject, type); result.add(pair); } } return result; } else { CodeSyncElement cse = (CodeSyncElement) node; List<Pair<Object, String>> result = new ArrayList<Pair<Object, String>>(); for (CodeSyncElement child : cse.getChildren()) { if (child.getType().equals(CodeSyncPlugin.FOLDER)) { Pair<Object, String> pair = new Pair<Object, String>(child, child.getType()); result.add(pair); } } return result; } } @Override public Boolean nodeHasChildren(Object node, TreeNode treeNode, GenericTreeContext context) { CodeSyncElement cse = (CodeSyncElement) node; if (cse.getChildren() != null && cse.getChildren().size() > 0) { return true; } return false; } @Override public boolean populateTreeNode(Object source, TreeNode destination, GenericTreeContext context) { if (source instanceof CodeSyncElement) { destination.setLabel((String) CodeSyncOperationsService.getInstance().getKeyFeatureValue((CodeSyncElement) source)); destination.setIcon(CodeSyncPlugin.getInstance().getResourceUrl("images/folder.gif")); } return false; } @Override public PathFragment getPathFragmentForNode(Object node, String nodeType, GenericTreeContext context) { return new PathFragment((String) CodeSyncOperationsService.getInstance().getKeyFeatureValue((CodeSyncElement) node), ((CodeSyncElement) node).getType()); } @Override public String getLabelForLog(Object node, String nodeType) { return node.toString(); } @Override public String getInplaceEditorText(StatefulServiceInvocationContext context, List<PathFragment> fullPath) { // doesn't support this return null; } @Override public boolean setInplaceEditorText(StatefulServiceInvocationContext context, List<PathFragment> path, String text) { // doesn't support this return false; } }