/** * Queue all the parent elements for a label update. * * @param element the element whose label and parent labels need to be updated */ public void updateParentLabels(ISynchronizeModelElement element) { queueForLabelUpdate(element); while (element.getParent() != null) { element = (ISynchronizeModelElement) element.getParent(); queueForLabelUpdate(element); } }
private String getDebugDisplayLabel(ISynchronizeModelElement node) { if (node == null) { return "ROOT"; //$NON-NLS-1$ } if (node.getResource() != null) { return node.getResource().getFullPath().toString(); } return node.getName(); }
/** * This method is invoked whenever a node is removed the viewer by the provider or a sub-provider. * The handler removes any listener and notifies the root provider that a node was removed. The * node removed may have children for which a nodeRemoved callback was not invoked (see * modelObjectCleared). * * @param element the removed element * @param provider the provider that added the element */ public void nodeRemoved( ISynchronizeModelElement element, AbstractSynchronizeModelProvider provider) { element.removePropertyChangeListener(listener); this.provider.nodeRemoved(element, provider); if (Policy.DEBUG_SYNC_MODELS) { System.out.println( "Node removed: " + getDebugDisplayLabel(element) + " -> " + getDebugDisplayLabel((ISynchronizeModelElement) element.getParent()) + " : " + getDebugDisplayLabel(provider)); // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } }
/** * Calculate and propagate problem markers in the element model * * @param element the ssynchronize element */ private void propagateProblemMarkers(ISynchronizeModelElement element) { IResource resource = element.getResource(); if (resource != null) { String property = provider.calculateProblemMarker(element); // If it doesn't have a direct change, a parent might boolean recalculateParentDecorations = hadProblemProperty(element, property); if (recalculateParentDecorations) { ISynchronizeModelElement parent = (ISynchronizeModelElement) element.getParent(); if (parent != null) { propagateProblemMarkers(parent); } } } }
/** * This method is invoked whenever a model object (i.e. node) is cleared from the model. This is * similar to node removal but is deep. * * @param node the node that was cleared */ public void modelObjectCleared(ISynchronizeModelElement node) { node.removePropertyChangeListener(listener); this.provider.modelObjectCleared(node); if (Policy.DEBUG_SYNC_MODELS) { System.out.println("Node cleared: " + getDebugDisplayLabel(node)); // $NON-NLS-1$ } }
private void extractSynchronizeModelInfo( ISynchronizeModelElement d, IPath path, Vector<PatchFile> newList, Vector<PatchFile> removeList, Vector<PatchFile> changeList) { // Recursively traverse the tree for children and sort leaf elements into their respective // change kind sets. // Don't add entries for ChangeLog files though. if (d.hasChildren()) { IPath newPath = path.append(d.getName()); for (IDiffElement element : d.getChildren()) { if (element instanceof ISynchronizeModelElement) extractSynchronizeModelInfo( (ISynchronizeModelElement) element, newPath, newList, removeList, changeList); else { if (!(d.getName().equals("ChangeLog"))) { // $NON-NLS-1$ PatchFile p = new PatchFile(d.getResource()); int kind = d.getKind() & Differencer.CHANGE_TYPE_MASK; if (kind == Differencer.CHANGE) { changeList.add(p); } else if (kind == Differencer.ADDITION) { p.setNewfile(true); newList.add(p); } else if (kind == Differencer.DELETION) { p.setRemovedFile(true); removeList.add(p); } } else { this.changeLogModified = true; } } } } else { if (!(d.getName().equals("ChangeLog"))) { // $NON-NLS-1$ PatchFile p = new PatchFile(d.getResource()); int kind = d.getKind() & Differencer.CHANGE_TYPE_MASK; if (kind == Differencer.CHANGE) { changeList.add(p); } else if (kind == Differencer.ADDITION) { p.setNewfile(true); newList.add(p); } else if (kind == Differencer.DELETION) { p.setRemovedFile(true); removeList.add(p); } } else { this.changeLogModified = true; } } }
// none -> error // error -> none // none -> warning // warning -> none // warning -> error // error -> warning private boolean hadProblemProperty(ISynchronizeModelElement element, String property) { boolean hadError = element.getProperty(ISynchronizeModelElement.PROPAGATED_ERROR_MARKER_PROPERTY); boolean hadWarning = element.getProperty(ISynchronizeModelElement.PROPAGATED_WARNING_MARKER_PROPERTY); // Force recalculation of parents of phantom resources IResource resource = element.getResource(); if (resource != null && resource.isPhantom()) { return true; } if (hadError) { if (!(property == ISynchronizeModelElement.PROPAGATED_ERROR_MARKER_PROPERTY)) { element.setPropertyToRoot(ISynchronizeModelElement.PROPAGATED_ERROR_MARKER_PROPERTY, false); if (property != null) { // error -> warning element.setPropertyToRoot(property, true); } // error -> none // recalculate parents return true; } return false; } else if (hadWarning) { if (!(property == ISynchronizeModelElement.PROPAGATED_WARNING_MARKER_PROPERTY)) { element.setPropertyToRoot( ISynchronizeModelElement.PROPAGATED_WARNING_MARKER_PROPERTY, false); if (property != null) { // warning -> error element.setPropertyToRoot(property, true); return false; } // warning -> none return true; } return false; } else { if (property == ISynchronizeModelElement.PROPAGATED_ERROR_MARKER_PROPERTY) { // none -> error element.setPropertyToRoot(property, true); return false; } else if (property == ISynchronizeModelElement.PROPAGATED_WARNING_MARKER_PROPERTY) { // none -> warning element.setPropertyToRoot(property, true); return true; } return false; } }
/* * Method that can be called from the UI thread to update the view model. */ private void internalRunViewUpdate(final Runnable runnable, boolean preserveExpansion) { StructuredViewer viewer = getViewer(); IResource[] expanded = null; IResource[] selected = null; try { if (Utils.canUpdateViewer(viewer)) { viewer.getControl().setRedraw(false); if (preserveExpansion) { expanded = provider.getExpandedResources(); selected = provider.getSelectedResources(); } if (viewer instanceof AbstractTreeViewer && additionsMap == null) additionsMap = new HashMap(); } runnable.run(); } finally { if (Utils.canUpdateViewer(viewer)) { try { if (additionsMap != null && !additionsMap.isEmpty() && Utils.canUpdateViewer(viewer)) { for (Iterator iter = additionsMap.keySet().iterator(); iter.hasNext(); ) { ISynchronizeModelElement parent = (ISynchronizeModelElement) iter.next(); if (Policy.DEBUG_SYNC_MODELS) { System.out.println("Adding child view items of " + parent.getName()); // $NON-NLS-1$ } Set toAdd = (Set) additionsMap.get(parent); ((AbstractTreeViewer) viewer).add(parent, toAdd.toArray(new Object[toAdd.size()])); } additionsMap = null; } if (expanded != null) { provider.expandResources(expanded); } if (selected != null) { provider.selectResources(selected); } } finally { viewer.getControl().setRedraw(true); } } } ISynchronizeModelElement root = provider.getModelRoot(); if (root instanceof SynchronizeModelElement) ((SynchronizeModelElement) root).fireChanges(); }
/** * Add the element to the viewer. * * @param parent the parent of the element which is already added to the viewer * @param element the element to be added to the viewer */ protected void doAdd(ISynchronizeModelElement parent, ISynchronizeModelElement element) { if (additionsMap == null) { if (Policy.DEBUG_SYNC_MODELS) { System.out.println("Added view item " + element.getName()); // $NON-NLS-1$ } AbstractTreeViewer viewer = (AbstractTreeViewer) getViewer(); viewer.add(parent, element); } else { // Accumulate the additions if (Policy.DEBUG_SYNC_MODELS) { System.out.println("Queueing view item for addition " + element.getName()); // $NON-NLS-1$ } Set toAdd = (Set) additionsMap.get(parent); if (toAdd == null) { toAdd = new HashSet(); additionsMap.put(parent, toAdd); } toAdd.add(element); } }
private void prepareChangeLog(IProgressMonitor monitor) { Object element = selected.getFirstElement(); IResource resource = null; Vector<PatchFile> newList = new Vector<PatchFile>(); Vector<PatchFile> removeList = new Vector<PatchFile>(); Vector<PatchFile> changeList = new Vector<PatchFile>(); int totalChanges = 0; if (element instanceof IResource) { resource = (IResource) element; } else if (element instanceof ISynchronizeModelElement) { ISynchronizeModelElement sme = (ISynchronizeModelElement) element; resource = sme.getResource(); } else if (element instanceof IAdaptable) { resource = (IResource) ((IAdaptable) element).getAdapter(IResource.class); } if (resource == null) return; IProject project = resource.getProject(); // Get the repository provider so we can support multiple types of // code repositories without knowing exactly which (e.g. CVS, SVN, etc..). RepositoryProvider r = RepositoryProvider.getProvider(project); if (r == null) return; SyncInfoSet set = new SyncInfoSet(); Subscriber s = r.getSubscriber(); if (s == null) return; if (element instanceof ISynchronizeModelElement) { // We can extract the ChangeLog list from the synchronize view which // allows us to skip items removed from the view ISynchronizeModelElement d = (ISynchronizeModelElement) element; while (d.getParent() != null) d = (ISynchronizeModelElement) d.getParent(); extractSynchronizeModelInfo(d, new Path(""), newList, removeList, changeList); totalChanges = newList.size() + removeList.size() + changeList.size(); } else { // We can then get a list of all out-of-sync resources. s.collectOutOfSync(new IResource[] {project}, IResource.DEPTH_INFINITE, set, monitor); SyncInfo[] infos = set.getSyncInfos(); totalChanges = infos.length; // Iterate through the list of changed resources and categorize them into // New, Removed, and Changed lists. for (SyncInfo info : infos) { int kind = SyncInfo.getChange(info.getKind()); PatchFile p = new PatchFile(info.getLocal()); // Check the type of entry and sort into lists. Do not add an entry // for ChangeLog files. if (!(p.getPath().lastSegment().equals("ChangeLog"))) { // $NON-NLS-1$ if (kind == SyncInfo.ADDITION) { p.setNewfile(true); newList.add(p); } else if (kind == SyncInfo.DELETION) { p.setRemovedFile(true); removeList.add(p); } else if (kind == SyncInfo.CHANGE) { if (info.getLocal().getType() == IResource.FILE) { changeList.add(p); } } } else { this.changeLogModified = true; } } } if (totalChanges == 0) return; // nothing to parse PatchFile[] patchFileInfoList = new PatchFile[totalChanges]; // Group like changes together and sort them by path name. // We want removed files, then new files, then changed files. // To get this, we put them in the array in reverse order. int index = 0; if (changeList.size() > 0) { // Get the repository provider so we can support multiple types of // code repositories without knowing exactly which (e.g. CVS, SVN, etc..). Collections.sort(changeList, new PatchFileComparator()); int size = changeList.size(); for (int i = 0; i < size; ++i) { PatchFile p = changeList.get(i); getChangedLines(s, p, monitor); patchFileInfoList[index + (size - i - 1)] = p; } index += size; } if (newList.size() > 0) { Collections.sort(newList, new PatchFileComparator()); int size = newList.size(); for (int i = 0; i < size; ++i) patchFileInfoList[index + (size - i - 1)] = newList.get(i); index += size; } if (removeList.size() > 0) { Collections.sort(removeList, new PatchFileComparator()); int size = removeList.size(); for (int i = 0; i < size; ++i) patchFileInfoList[index + (size - i - 1)] = removeList.get(i); } // now, find out modified functions/classes. // try to use the the extension point. so it can be extended easily // for all files in patch file info list, get function guesses of each // file. monitor.subTask(Messages.getString("ChangeLog.WritingMessage")); // $NON-NLS-1$ int unitwork = 250 / patchFileInfoList.length; for (PatchFile pf : patchFileInfoList) { // for each file if (pf != null) { // any ChangeLog changes will have null entries for them String[] funcGuessList = guessFunctionNames(pf); outputMultipleEntryChangeLog(pf, funcGuessList); } monitor.worked(unitwork); } }