| /******************************************************************************* |
| * Copyright (c) 2000, 2017 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.dltk.ui.browsing; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.core.runtime.Assert; |
| import org.eclipse.dltk.core.DLTKCore; |
| import org.eclipse.dltk.core.ElementChangedEvent; |
| import org.eclipse.dltk.core.IElementChangedListener; |
| import org.eclipse.dltk.core.IModelElement; |
| import org.eclipse.dltk.core.IModelElementDelta; |
| import org.eclipse.dltk.core.IScriptFolder; |
| import org.eclipse.dltk.core.IScriptProject; |
| import org.eclipse.dltk.core.ModelException; |
| import org.eclipse.dltk.ui.DLTKUIPlugin; |
| import org.eclipse.jface.util.IPropertyChangeListener; |
| import org.eclipse.jface.util.PropertyChangeEvent; |
| import org.eclipse.jface.viewers.StructuredViewer; |
| import org.eclipse.jface.viewers.TreeViewer; |
| import org.eclipse.jface.viewers.Viewer; |
| |
| abstract class LogicalPackagesProvider implements IPropertyChangeListener, IElementChangedListener { |
| |
| protected static final Object[] NO_CHILDREN= new Object[0]; |
| |
| protected Map fMapToLogicalPackage; |
| protected Map fMapToPackageFragments; |
| protected boolean fCompoundState; |
| protected StructuredViewer fViewer; |
| protected boolean fInputIsProject; |
| |
| public LogicalPackagesProvider(StructuredViewer viewer){ |
| fViewer= viewer; |
| fCompoundState= isInCompoundState(); |
| fInputIsProject= true; |
| fMapToLogicalPackage= new HashMap(); |
| fMapToPackageFragments= new HashMap(); |
| DLTKUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this); |
| } |
| |
| /** |
| * Adds the given fragments to the internal map. |
| * Existing fragments will be replaced by the new ones. |
| * |
| * @param packageFragments the package fragments to add |
| */ |
| protected void addFragmentsToMap(IScriptFolder[] packageFragments) { |
| for (int i= 0; i < packageFragments.length; i++) { |
| IScriptFolder fragment= packageFragments[i]; |
| String key= getKey(fragment); |
| fMapToPackageFragments.put(key, fragment); |
| } |
| } |
| |
| protected String getKey(IScriptFolder fragment) { |
| return fragment.getElementName() + fragment.getScriptProject().getElementName(); |
| } |
| |
| /** |
| * Returns the logical package for the given package fragment |
| * or <code>null</code> if it is not grouped by logical package. |
| * |
| * @param fragment the package fragment |
| * @return the logical package |
| */ |
| public LogicalPackage findLogicalPackage(IScriptFolder fragment) { |
| Assert.isNotNull(fragment); |
| if (isInCompoundState()) |
| return (LogicalPackage)fMapToLogicalPackage.get(getKey(fragment)); |
| else |
| return null; |
| } |
| |
| /** |
| * Combines packages with same names into a logical package which will |
| * be added to the resulting array. If a package is not yet in this content |
| * provider then the package fragment is added to the resulting array. |
| * |
| * @param packageFragments the package fragments to combine |
| * @return an array with combined (logical) packages and package fragments |
| */ |
| protected Object[] combineSamePackagesIntoLogialPackages(IScriptFolder[] packageFragments) { |
| |
| if (!fCompoundState) |
| return packageFragments; |
| |
| List newChildren= new ArrayList(); |
| |
| for (int i= 0; i < packageFragments.length; i++) { |
| IScriptFolder fragment= packageFragments[i]; |
| |
| if (fragment == null) |
| continue; |
| |
| LogicalPackage lp= findLogicalPackage(fragment); |
| |
| if (lp != null) { |
| if (lp.belongs(fragment)) { |
| lp.add(fragment); |
| } |
| if(!newChildren.contains(lp)) |
| newChildren.add(lp); |
| |
| } else { |
| String key= getKey(fragment); |
| IScriptFolder frag= (IScriptFolder)fMapToPackageFragments.get(key); |
| if (frag != null && !fragment.equals(frag)) { |
| lp= new LogicalPackage(frag); |
| lp.add(fragment); |
| newChildren.remove(frag); |
| newChildren.add(lp); |
| fMapToLogicalPackage.put(key, lp); |
| fMapToPackageFragments.remove(frag); |
| } else { |
| fMapToPackageFragments.put(key, fragment); |
| newChildren.add(fragment); |
| } |
| } |
| } |
| return newChildren.toArray(); |
| } |
| |
| @Override |
| public void propertyChange(PropertyChangeEvent event) { |
| if (fCompoundState == isInCompoundState()) |
| return; |
| else |
| fCompoundState= isInCompoundState(); |
| |
| if (!isInCompoundState()) { |
| fMapToLogicalPackage.clear(); |
| fMapToPackageFragments.clear(); |
| } |
| |
| if(fViewer instanceof TreeViewer){ |
| TreeViewer viewer= (TreeViewer) fViewer; |
| Object[] expandedObjects= viewer.getExpandedElements(); |
| viewer.refresh(); |
| viewer.setExpandedElements(expandedObjects); |
| } else |
| fViewer.refresh(); |
| } |
| |
| protected boolean isInCompoundState() { |
| // XXX: for now we don't offer a preference might become a view menu entry |
| // return AppearancePreferencePage.logicalPackagesInPackagesView(); |
| return true; |
| } |
| |
| public void dispose(){ |
| DLTKUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this); |
| fMapToLogicalPackage= null; |
| fMapToPackageFragments= null; |
| } |
| |
| public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { |
| if (newInput != null) { |
| DLTKCore.addElementChangedListener(this); |
| } else { |
| DLTKCore.removeElementChangedListener(this); |
| } |
| fInputIsProject= (newInput instanceof IScriptProject); |
| |
| if(viewer instanceof StructuredViewer) |
| fViewer= (StructuredViewer)viewer; |
| } |
| |
| abstract protected void processDelta(IModelElementDelta delta) throws ModelException; |
| |
| /* |
| * @since 3.0 |
| */ |
| protected boolean isClassPathChange(IModelElementDelta delta) { |
| |
| // need to test the flags only for package fragment roots |
| if (delta.getElement().getElementType() != IModelElement.PROJECT_FRAGMENT ) |
| return false; |
| |
| int flags= delta.getFlags(); |
| return (delta.getKind() == IModelElementDelta.CHANGED && |
| ((flags & IModelElementDelta.F_ADDED_TO_BUILDPATH) != 0) || |
| ((flags & IModelElementDelta.F_REMOVED_FROM_BUILDPATH) != 0) || |
| ((flags & IModelElementDelta.F_REORDER) != 0)); |
| } |
| |
| @Override |
| public void elementChanged(ElementChangedEvent event) { |
| try { |
| processDelta(event.getDelta()); |
| } catch (ModelException e) { |
| DLTKUIPlugin.log(e); |
| } |
| } |
| |
| } |