private void processRoot(final SModelRootEvent event) { SNode root = event.getRoot(); final boolean added = event.isAdded(); if ((added ? root.getModel() == null : root.getModel() != null)) { return; } final SNodeId rootId = root.getNodeId(); runUpdateTask( new _FunctionTypes._void_P0_E0() { public void invoke() { if (added) { removeChanges( rootId, DeleteRootChange.class, new _FunctionTypes._return_P1_E0<Boolean, DeleteRootChange>() { public Boolean invoke(DeleteRootChange ch) { return true; } }); buildAndAddChanges( new _FunctionTypes._void_P1_E0<ChangeSetBuilder>() { public void invoke(ChangeSetBuilder b) { b.buildForNode(getOldNode(rootId), event.getRoot()); } }); } else { if (removeChanges( rootId, AddRootChange.class, new _FunctionTypes._return_P1_E0<Boolean, AddRootChange>() { public Boolean invoke(AddRootChange ch) { return true; } }) == 0) { // root was not added removeDescendantChanges(rootId); buildAndAddChanges( new _FunctionTypes._void_P1_E0<ChangeSetBuilder>() { public void invoke(ChangeSetBuilder b) { b.buildForNode(getOldNode(rootId), null); } }); } } } }, null, event); }
@Override public final SNode doSubstitute(@Nullable final EditorContext editorContext, String pattern) { SNode parentNode = getSourceNode(); SNode newChild = createChildNode(getParameterObject(), parentNode.getModel(), pattern); if (newChild != null) { SNode result = mySetter.execute(parentNode, myCurrentChild, newChild, editorContext); if (result != newChild) { // node was wrapped by mySetter return result; } return selectChildNode(result, parentNode.getModel(), pattern, editorContext); } return null; }
private void processReference(SModelReferenceEvent event) { SReference ref = event.getReference(); final SNode sourceNode = ref.getSourceNode(); if (sourceNode.getModel() == null) { return; } final SNodeId nodeId = sourceNode.getNodeId(); final String role = ref.getRole(); runUpdateTask( new _FunctionTypes._void_P0_E0() { public void invoke() { removeChanges( nodeId, SetReferenceChange.class, new _FunctionTypes._return_P1_E0<Boolean, SetReferenceChange>() { public Boolean invoke(SetReferenceChange ch) { return role.equals(ch.getRole()); } }); buildAndAddChanges( new _FunctionTypes._void_P1_E0<ChangeSetBuilder>() { public void invoke(ChangeSetBuilder b) { b.buildForReference(getOldNode(nodeId), sourceNode, role); } }); } }, event.getReference().getSourceNode(), event); }
@Override protected void addReferenceCell(final SReferenceLink referenceLink) { SReference reference = getNode().getReference(referenceLink); if (reference == null) { addLabel("<no target>"); return; } final SNode referentNode = reference.getTargetNode(); if (referentNode == null) { String resolveInfo = ((jetbrains.mps.smodel.SReference) reference).getResolveInfo(); String myErrorText = resolveInfo != null ? resolveInfo : "?" + referenceLink.getName() + "?"; EditorCell_Error errorCell = new EditorCell_Error(getEditorContext(), getNode(), myErrorText); errorCell.setCellId("error_" + referenceLink.getName()); addCell(errorCell); return; } if (referentNode.getModel() == null) { LOG.error("Reference to node which is not inside model. Node: " + referentNode, referentNode); } EditorCell cell = getUpdateSession() .updateReferencedNodeCell( new Computable<EditorCell>() { @Override public EditorCell compute() { return createReferentEditorCell( getEditorContext(), referenceLink, referentNode); } }, referentNode, referenceLink.getName()); setSemanticNodeToCells(cell, getNode()); cell.setCellId("reference_" + referenceLink.getName()); addCell(cell); }
public void execute(SNode node) { SReference ref = node.getReference(((String) makeReferenceStatic_QuickFix.this.getField("role")[0])); SNode target = ref.getTargetNode(); if (target == null) { return; } SReference staticRef = StaticReference.create( ((String) makeReferenceStatic_QuickFix.this.getField("role")[0]), node, target); node.setReference(((String) makeReferenceStatic_QuickFix.this.getField("role")[0]), staticRef); // add model import ((SModelBase) node.getModel()).addModelImport(target.getModel().getReference(), true); }
private boolean checkCondition(TemplateContext context, ITemplateGenerator generator) throws GenerationFailureException { if (baseRuleCondition == null) { return true; } try { return (Boolean) QueryMethodGenerated.invoke( myConditionMethodName, generator.getGeneratorSessionContext(), new ReductionRuleQueryContext(context, ruleNode, generator), ruleNode.getModel(), true); } catch (ClassNotFoundException e) { String msg = String.format( "cannot find condition method '%s' : evaluate to FALSE", myConditionMethodName); generator.getLogger().warning(baseRuleCondition, msg); } catch (NoSuchMethodException e) { String msg = String.format( "cannot find condition method '%s' : evaluate to FALSE", myConditionMethodName); generator.getLogger().warning(baseRuleCondition, msg); } catch (Throwable t) { generator.getLogger().handleException(t); String msg = String.format("error executing condition '%s', see exception", myConditionMethodName); generator.getLogger().error(baseRuleCondition, msg); throw new GenerationFailureException(t); } return false; }
private void processProperty(SModelPropertyEvent event) { final SNode node = event.getNode(); if (node.getModel() == null) { return; } final SNodeId nodeId = node.getNodeId(); final String propertyName = event.getPropertyName(); runUpdateTask( new _FunctionTypes._void_P0_E0() { public void invoke() { removeChanges( nodeId, SetPropertyChange.class, new _FunctionTypes._return_P1_E0<Boolean, SetPropertyChange>() { public Boolean invoke(SetPropertyChange ch) { return propertyName.equals(ch.getPropertyName()); } }); buildAndAddChanges( new _FunctionTypes._void_P1_E0<ChangeSetBuilder>() { public void invoke(ChangeSetBuilder b) { b.buildForProperty(getOldNode(nodeId), node, propertyName); } }); } }, node, event); }
protected boolean isValidEditor() { SNode node = getEditedNode(); if (node == null) return false; SModel model = node.getModel(); if (model != null && jetbrains.mps.util.SNodeOperations.isModelDisposed(model)) return false; return true; }
private void addModelListener(SNode node) { SModel sModel = node.getModel(); SModel descriptor = sModel; if (descriptor != null && !myListeningForModels.contains(descriptor)) { ((SModelInternal) descriptor).addModelListener(myModelListener); myListeningForModels.add(descriptor); } }
public MPSTreeNodeEx findMostSuitableSNodeTreeNode(@NotNull SNode node) { SModel model = node.getModel(); if (model == null) return null; SModelTreeNode modelNode = findMostSuitableModelTreeNode(model); if (modelNode == null) return null; return findSNodeTreeNodeInParent(node, modelNode); }
public static SNode addNewChild(SNode node, String role, String childConceptFQName) { if (node != null) { SNode newChild = SModelOperations.createNewNode(node.getModel(), childConceptFQName); node.addChild(role, newChild); return newChild; } return null; }
public static SNode setNewChild(SNode node, String role, String childConceptFQName) { if (node != null) { SNode newChild = SModelOperations.createNewNode(node.getModel(), childConceptFQName); SLinkOperations.setTarget(node, role, newChild, true); return newChild; } return null; }
public static TextGenerationResult generateText( SNode node, boolean withDebugInfo, @Nullable StringBuilder[] buffers) { TextGenBuffer buffer = new TextGenBuffer(withDebugInfo, buffers); buffer.putUserObject(PACKAGE_NAME, node.getModel().getLongName()); buffer.putUserObject(ROOT_NODE, node); appendNodeText(buffer, node, null); String topBufferText = buffer.getTopBufferText(); int topLength = topBufferText.isEmpty() ? 1 : topBufferText.split(buffer.getLineSeparator(), -1).length + 2; // position info Map<SNode, TraceablePositionInfo> positionInfo = null; Map<SNode, ScopePositionInfo> scopeInfo = null; Map<SNode, UnitPositionInfo> unitInfo = null; if (withDebugInfo) { positionInfo = TraceInfoGenerationUtil.getUserObjects(buffer, TraceInfoGenerationUtil.POSITION_INFO); scopeInfo = TraceInfoGenerationUtil.getUserObjects(buffer, TraceInfoGenerationUtil.SCOPE_INFO); unitInfo = TraceInfoGenerationUtil.getUserObjects(buffer, TraceInfoGenerationUtil.UNIT_INFO); adjustPositions(topLength, positionInfo); adjustPositions(topLength, scopeInfo); adjustPositions(topLength, unitInfo); } // dependencies List<String> dependencies = getUserObjectCollection( DEPENDENCY, node, buffer, (Set<String>) buffer.getUserObject(EXTENDS)); List<String> extend = getUserObjectCollection(EXTENDS, node, buffer, null); Map<String, List<String>> deps = new HashMap<String, List<String>>(2); deps.put(DEPENDENCY, dependencies); deps.put(EXTENDS, extend); Object result = buffer.getText(); String outputEncoding = (String) buffer.getUserObject(OUTPUT_ENCODING); if (outputEncoding != null) { if (outputEncoding.equals("binary")) { result = EncodingUtil.decodeBase64((String) result); } else { try { result = EncodingUtil.encode((String) result, outputEncoding); } catch (IOException ex) { buffer.foundError("cannot encode the output stream", null, ex); } } } return new TextGenerationResult( node, result, buffer.hasErrors(), buffer.problems(), positionInfo, scopeInfo, unitInfo, deps); }
@Override public void execute(EditorContext context) { LOG.assertInCommand(); EditorComponent editorComponent = (EditorComponent) context.getEditorComponent(); EditorCell selectedCell = editorComponent.getSelectedCell(); SNode anchorNode = selectedCell.getSNode(); PasteNodeData pasteNodeData = CopyPasteUtil.getPasteNodeDataFromClipboard(anchorNode.getModel()); if (pasteNodeData == null || pasteNodeData.getNodes().isEmpty()) { pasteNodeData = CopyPasteUtil.getConvertedFromClipboard( anchorNode.getModel(), context.getOperationContext().getProject()); if (pasteNodeData == null) return; } List<SNode> pasteNodes = pasteNodeData.getNodes(); Set<SReference> requireResolveReferences = pasteNodeData.getRequireResolveReferences(); new NodePaster(pasteNodes).pasteRelative(anchorNode, myPastePlaceHint); ResolverComponent.getInstance() .resolveScopesOnly(requireResolveReferences, context.getOperationContext()); // set selection editorComponent.flushEvents(); EditorCell nodeCell = editorComponent.findNodeCell(pasteNodes.get(0)); if (nodeCell == null) return; // after 'set reference'? EditorCell_Label labelCell = CellFinderUtil.findChildByClass(nodeCell, EditorCell_Label.class, true); if (labelCell != null) { editorComponent.changeSelection(labelCell); } if (pasteNodes.size() == 1) { editorComponent.pushSelection(nodeCell); } else { SelectionManager selectionManager = editorComponent.getSelectionManager(); selectionManager.pushSelection( selectionManager.createRangeSelection( pasteNodes.get(0), pasteNodes.get(pasteNodes.size() - 1))); } }
protected IOperationContext createOperationContext() { if (myContext != null) { return myContext; } assert isValid() : "createOperationContext() was called for MPSFileNodeEditor with invalid file: " + myFile; SNode node = myFile.getNode(); if (node == null || node.getModel() == null || node.getModel().getModelDescriptor() == null) { myIsValid = false; return null; } SModelDescriptor sm = node.getModel().getModelDescriptor(); IOperationContext result = new ModuleContext(sm.getModule(), ProjectHelper.toMPSProject(myProject)); assert result.getModule() == sm.getModule() : "Different modules: " + result.getModule() + "/" + sm.getModule(); return result; }
public static TextGenerationResult generateText( SNode node, boolean failIfNoTextgen, boolean withDebugInfo, @Nullable StringBuilder[] buffers) { if (canGenerateTextFor(node)) { return generateText(node, withDebugInfo, buffers); } else if (failIfNoTextgen) { String error = "Can't generate text from " + node; Message m = new Message(MessageKind.ERROR, error); if (node != null && node.getModel() != null && !node.getModel().isTransient()) { m.setHintObject(new jetbrains.mps.smodel.SNodePointer(node)); } return new TextGenerationResult( node, NO_TEXTGEN, true, Collections.<IMessage>singleton(m), null, null, null, null); } else { return new TextGenerationResult( node, NO_TEXTGEN, false, Collections.<IMessage>emptyList(), null, null, null, null); } }
@Override public boolean canExecute(EditorContext context) { EditorCell selectedCell = (EditorCell) context.getSelectedCell(); if (selectedCell == null) { return false; } SNode anchorNode = selectedCell.getSNode(); if (anchorNode == null) { return false; } List<SNode> pasteNodes = CopyPasteUtil.getNodesFromClipboard(anchorNode.getModel()); if (pasteNodes == null || pasteNodes.isEmpty()) { return CopyPasteUtil.isConversionAvailable(anchorNode.getModel(), anchorNode); } if (!new NodePaster(pasteNodes).canPasteRelative(anchorNode)) { LOG.debug("Couldn't paste node relative"); return false; } return true; }
private boolean checkContext(SNode contextNode) { TemplateGenerator generator = myEnv.getGenerator(); if (contextNode == null) { myEnv .getLogger() .error( myRule.getRuleNode(), "weaving rule: cannot find context node", GeneratorUtil.describe(myApplicableNode, "input node")); return false; } // Additional check - context should be generated from the same root SNode contextRoot = contextNode.getContainingRoot(); SModel model = contextRoot.getModel(); if (model == null) { return reportErrorIfStrict( "bad context for weaving rule: no root for context " + contextNode); } SNode originalContextRoot = generator.getOriginalRootByGenerated(contextRoot); if (originalContextRoot == null) { return reportErrorIfStrict( String.format( "bad context for weaving rule: %s is generated by 'create root' rule", contextRoot)); } if (myApplicableNode.getModel() == null) return true; SNode inputRoot = myApplicableNode.getContainingRoot(); if (originalContextRoot != inputRoot) { String msg = "bad context for weaving rule: %s is generated from %s , while input node is from %s"; return reportErrorIfStrict(String.format(msg, contextRoot, originalContextRoot, inputRoot)); } return true; }
@Override @Nullable public WarningPanel getWarningPanel(@NotNull SNode node, @NotNull Project project) { SModel model = node.getModel(); if (model != null) { SModule module = model.getModule(); if (module != null && module.isReadOnly()) { return new WarningPanel( this, "Warning: the node is in a read-only model. Your changes won't be saved"); } } return null; }
private boolean checkResolvedTarget(AbstractTemplateGenerator generator, SNode outputTargetNode) { Status status = generator .getReferentRoleValidator(myOutputSourceNode, myReferenceRole) .validate(outputTargetNode); if (status != null) { generator .getLogger() .error( myOutputSourceNode.getReference(), status.getMessage(getClass().getSimpleName()), getErrorDescriptions()); return false; } SModel referentNodeModel = outputTargetNode.getModel(); if (referentNodeModel != null && referentNodeModel != myOutputSourceNode.getModel()) { if (SModelStereotype.isGeneratorModel(referentNodeModel)) { // references to template nodes are not acceptable String msg = "bad reference, cannot refer to a generator model: %s for role '%s' in %s"; generator .getLogger() .error( myOutputSourceNode.getReference(), String.format( msg, SNodeUtil.getDebugText(outputTargetNode), myReferenceRole, SNodeUtil.getDebugText(myOutputSourceNode)), getErrorDescriptions()); return false; } if (referentNodeModel.getModule() instanceof TransientModelsModule) { // references to transient nodes in a model outside one being generated are not acceptable String msg = "bad reference, cannot refer to an external transient model: %s for role '%s' in %s"; generator .getLogger() .error( myOutputSourceNode.getReference(), String.format( msg, SNodeUtil.getDebugText(outputTargetNode), myReferenceRole, SNodeUtil.getDebugText(myOutputSourceNode)), getErrorDescriptions()); return false; } } return true; }
@Nullable public static GeneratedSourcePosition fromNode(final SNode node) { SModel model = node.getModel().getModelDescriptor(); DebugInfo debugInfo = TraceInfoCache.getInstance().get(model); if (debugInfo == null) { return null; } TraceablePositionInfo position = debugInfo.getPositionForNode(node); if (position == null) return null; return new GeneratedSourcePosition( TraceInfoUtil.getUnitName(position.getFileName(), position.getStartLine(), model), position.getFileName(), position.getStartLine()); }
private static StringBuilder checkModel(final SModel sm) { StringBuilder errorMessages = new StringBuilder(); List<String> validationResult = ModelAccess.instance() .runReadAction( new Computable<List<String>>() { public List<String> compute() { return new ModelValidator(sm).validate(); } }); if (!(validationResult.isEmpty())) { errorMessages.append("errors in model: ").append(sm.getReference().toString()).append("\n"); for (String item : validationResult) { errorMessages.append("\t"); errorMessages.append(item); errorMessages.append("\n"); } } for (SNode node : SNodeUtil.getDescendants(sm)) { // Testbench.LOG.debug("Checking node " + node); if (SModelUtil.findConceptDeclaration(node.getConcept().getQualifiedName()) == null) { errorMessages.append("Unknown concept "); errorMessages.append(node.getConcept().getQualifiedName()); errorMessages.append("\n"); } } for (SNode node : SNodeUtil.getDescendants(sm)) { for (SReference ref : node.getReferences()) { if (jetbrains.mps.smodel.SNodeUtil.hasReferenceMacro(node, ref.getRole())) { continue; } if (SNodeOperations.getTargetNodeSilently(ref) == null) { errorMessages .append("Broken reference in model {") .append(SNodeOperations.getModelLongName(node.getModel())) .append("}") .append(" node ") .append(node.getNodeId().toString()) .append("(") .append(node) .append(")\n"); } } } return errorMessages; }
public static void warnIfUnitNameInvalid(String unitName, SNode node) { String longName = SModelStereotype.withoutStereotype(node.getModel().getReference().getModelName()); if (!(unitName.startsWith(longName))) { LOG.warning( "Unit name has to start with model fqName. Fix " + unitName + " in " + longName + ".", node); } else if (unitName.length() <= longName.length() + 1 || !(unitName.substring(longName.length()).startsWith(".")) || unitName.substring(longName.length() + 1).contains(".")) { LOG.warning( "Unit name has to match \"modelFqName.shortUnitName\" where short unit name does not contain dots. Fix " + unitName + " in " + longName + ".", node); } }
void build() { for (SNode cd : myLanguage.getConceptDeclarations()) { if (!(cd.getModel() != null && cd.getParent() == null)) continue; if (!SNodeUtil.isDefaultSubstitutable(cd)) { continue; } String fqName = NameUtil.nodeFQName(cd); for (String ancestor : getAncestorsNames_internal(fqName)) { Set<String> addTo = mySubconcepts.get(ancestor); if (addTo == null) { addTo = new HashSet<String>(); mySubconcepts.put(ancestor, addTo); } addTo.add(fqName); } } }
@Override public boolean isApplicable(TemplateExecutionEnvironment environment, TemplateContext context) throws GenerationFailureException { SNode condition = RuleUtil.getDropRuleCondition(ruleNode); if (condition == null) { // condition is not required return true; } String methodName = TemplateFunctionMethodName.dropRootRule_Condition(condition); try { return (Boolean) QueryMethodGenerated.invoke( methodName, environment.getGenerator().getGeneratorSessionContext(), new DropRootRuleContext(context.getInput(), ruleNode, environment.getGenerator()), ruleNode.getModel(), true); } catch (ClassNotFoundException e) { environment .getGenerator() .getLogger() .warning( condition, "cannot find condition method '" + methodName + "' : evaluate to TRUE"); } catch (NoSuchMethodException e) { environment .getGenerator() .getLogger() .warning( condition, "cannot find condition method '" + methodName + "' : evaluate to TRUE"); } catch (Throwable t) { environment.getGenerator().getLogger().handleException(t); environment .getGenerator() .getLogger() .error(condition, "error executing condition " + methodName + " (see exception)"); throw new GenerationFailureException(t); } // in this case 'true' is better default return true; }
public void apply() { if (myNodesToApply.isEmpty()) { return; } SNode first = myNodesToApply.iterator().next(); SModel model = first.getModel(); if (model == null) { LOG.warning( "Checking node which is not attached to the model: " + first.getPresentation() + " " + first.getNodeId()); return; } // XXX could I demand here that model has to be attached to a repository, so that I can use one // to obtain LanguageRegistry? for (SLanguage language : SModelOperations.getAllLanguageImports(model)) { LanguageRuntime languageRuntime = LanguageRegistry.getInstance().getLanguage(language); if (languageRuntime == null) { continue; } DataFlowAspectDescriptor aspect = languageRuntime.getAspect(DataFlowAspectDescriptor.class); if (aspect == null) { continue; } for (DataFlowConstructor rule : aspect.getConstructors(myAnalyzerId)) { myRules.add(rule); } } Set<SNode> descendants = new LinkedHashSet<SNode>(); for (SNode myNodeToApply : myNodesToApply) { descendants.addAll( SNodeOperations.getNodeDescendants( myNodeToApply, null, false, new SAbstractConcept[] {})); } for (SNode descendant : descendants) { getRules(descendant).forEach(rule -> rule.performActions(myProgram, descendant)); } }
private void removeOwnerForRootNodeContext(final SNode node, final ITypeContextOwner owner) { ModelAccess.assertLegalRead(); if (node == null || node.getModel() == null) return; final SNode rootNode = node.getContainingRoot(); // if node is disposed, then context was removed by beforeModelDisposed/beforeRootDeleted // listener synchronized (myLock) { SNodeReference rootNodePointer = new jetbrains.mps.smodel.SNodePointer(rootNode); List<TypecheckingContextHolder> contextWithOwners = myTypeCheckingContexts.get(rootNodePointer); if (contextWithOwners != null) { for (ListIterator<TypecheckingContextHolder> it = contextWithOwners.listIterator(); it.hasNext(); ) { TypecheckingContextHolder contextHolder = it.next(); ITypeContextOwner o = contextHolder.getOwner(); if (o == owner) { if (!owner.reuseTypecheckingContext()) { contextHolder.release(); if (!contextHolder.isActive()) { it.remove(); } } else { contextHolder.release(); if (!contextHolder.isActive()) { it.remove(); } } break; } } if (contextWithOwners.isEmpty()) { myTypeCheckingContexts.remove(rootNodePointer); } } } }
@Override protected SNode findInConcept(SNode cnode) { SModel model = cnode.getModel(); return model.getNode(new SNodeId.Regular(myRoleId.getIdValue())); }
public static Iterable<SNode> getAvailableConcepts( SNode contextNode, final SAbstractConcept metaConcept) { SModule contextModule = contextNode.getModel().getModule(); Set<Language> contextLanguages = SetSequence.fromSet(new HashSet<Language>()); for (SModule module : CollectionSequence.fromCollection( new GlobalModuleDependenciesManager(contextModule) .getModules(GlobalModuleDependenciesManager.Deptype.VISIBLE))) { if (module instanceof Language) { SetSequence.fromSet(contextLanguages).addElement((Language) module); } } Collection<Language> usedLanguages = new GlobalModuleDependenciesManager(contextModule).getUsedLanguages(); Iterable<SModel> strucModels = SetSequence.fromSet(contextLanguages) .select( new ISelector<Language, SModel>() { public SModel select(Language it) { return it.getStructureModelDescriptor(); } }) .union( CollectionSequence.fromCollection(usedLanguages) .translate( new ITranslator2<Language, SModel>() { public Iterable<SModel> translate(Language it) { return it.getAccessoryModels(); } }) .where( new IWhereFilter<SModel>() { public boolean accept(SModel it) { return LanguageAspect.STRUCTURE.is(it); } })) .where( new IWhereFilter<SModel>() { public boolean accept(SModel it) { return it != null; } }); return Sequence.fromIterable(strucModels) .translate( new ITranslator2<SModel, SNode>() { public Iterable<SNode> translate(SModel it) { return (Iterable<SNode>) it.getRootNodes(); } }) .where( new IWhereFilter<SNode>() { public boolean accept(SNode it) { return SNodeOperations.isInstanceOf(it, SNodeOperations.asSConcept(metaConcept)); } }) .select( new ISelector<SNode, SNode>() { public SNode select(SNode it) { return SNodeOperations.cast( it, MetaAdapterFactory.getInterfaceConcept( 0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x110396eaaa4L, "jetbrains.mps.lang.core.structure.INamedConcept")); } }); }
private void processChild(SModelChildEvent event, Map<SNode, Set<String>> childChanged) { SNode parent = event.getParent(); if (parent.getModel() == null) { return; } final String childRole = event.getChildRole(); // tyring to avoid update task execution for the same child role twice Set<String> childRoles = MapSequence.fromMap(childChanged).get(parent); if (childRoles == null) { childRoles = SetSequence.fromSet(new HashSet<String>()); MapSequence.fromMap(childChanged).put(parent, childRoles); } if (SetSequence.fromSet(childRoles).contains(childRole)) { return; } else { SetSequence.fromSet(childRoles).addElement(childRole); } final SNodeId parentId = parent.getNodeId(); final Wrappers._T<List<? extends SNode>> childrenRightAfterEvent = new Wrappers._T<List<? extends SNode>>( IterableUtil.asList(parent.getChildren(childRole))); childrenRightAfterEvent.value = ListSequence.fromList(childrenRightAfterEvent.value) .select( new ISelector<SNode, SNode>() { public SNode select(SNode n) { return CopyUtil.copyAndPreserveId(n, false); } }) .toListSequence(); runUpdateTask( new _FunctionTypes._void_P0_E0() { public void invoke() { removeChanges( parentId, NodeGroupChange.class, new _FunctionTypes._return_P1_E0<Boolean, NodeGroupChange>() { public Boolean invoke(NodeGroupChange ch) { return childRole.equals(ch.getRole()); } }); removeDescendantChanges(parentId, childRole); myLastParentAndNewChildrenIds = MultiTuple.<SNodeId, List<SNodeId>>from( parentId, ListSequence.fromList(childrenRightAfterEvent.value) .select( new ISelector<SNode, SNodeId>() { public SNodeId select(SNode n) { return n.getNodeId(); } }) .toListSequence()); buildAndAddChanges( new _FunctionTypes._void_P1_E0<ChangeSetBuilder>() { public void invoke(ChangeSetBuilder b) { b.buildForNodeRole( IterableUtil.asList(getOldNode(parentId).getChildren(childRole)), childrenRightAfterEvent.value, parentId, childRole); } }); } }, parent, event); }