/** * <p>Copyright: Copyright (c) 2009</p> * <p>Company: �������ӹɷ����޹�˾</p> */ package com.hundsun.ares.studio.ui; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.widgets.Control; import org.eclipse.ui.model.IWorkbenchAdapter; import com.hundsun.ares.studio.core.ARESCore; import com.hundsun.ares.studio.core.ARESElementChangedEvent; import com.hundsun.ares.studio.core.ARESModelException; import com.hundsun.ares.studio.core.IARESElement; import com.hundsun.ares.studio.core.IARESElementChangeListener; import com.hundsun.ares.studio.core.IARESModule; import com.hundsun.ares.studio.core.IARESModuleRoot; import com.hundsun.ares.studio.core.IARESProject; import com.hundsun.ares.studio.core.IARESResource; import com.hundsun.ares.studio.core.IReferencedLibrary; import com.hundsun.ares.studio.core.model.ResGroup; import com.hundsun.ares.studio.core.registry.ARESResRegistry; import com.hundsun.ares.studio.core.registry.IModuleRootDescriptor; import com.hundsun.ares.studio.core.registry.IResCategoryDescriptor; import com.hundsun.ares.studio.core.registry.ModuleRootType2ResTypeMap; import com.hundsun.ares.studio.core.registry.ModulesRootTypeRegistry; import com.hundsun.ares.studio.core.util.ARESElementUtil; import com.hundsun.ares.studio.internal.core.ARESProject; /** * �����ṩ�� * @author sundl */ public class CommonElementContentProvider extends ARESElementContentProvider { protected TreeViewer viewer; protected Object input; // ģ��չʾΪ���ӽṹ����ƽ���ṹ protected boolean flatLayout = false; // �Ƿ���ʾ��Դ���� protected boolean showCategory = true; // �Ƿ���ʾ���� protected boolean showGroup = true; private IPropertyChangeListener propertyListener; private IARESElementChangeListener elementListener; private IResourceChangeListener resListener; private Map<IARESModule, ARESResourceCategory[]> catesMap = new HashMap<IARESModule, ARESResourceCategory[]>(); public CommonElementContentProvider() { this(true); } public CommonElementContentProvider(boolean refresh) { IPreferenceStore store = ARESUI.INSTANCE.getPreferenceStore(); flatLayout = store.getBoolean(ARESPreferences.FLATLAYOUT); showCategory = store.getBoolean(ARESPreferences.SHOW_CATEGORY); propertyListener = new IPropertyChangeListener() { public void propertyChange(PropertyChangeEvent event) { if (event.getProperty().equals(ARESPreferences.FLATLAYOUT)) { boolean newValue = ((Boolean) event.getNewValue()).booleanValue() ? true : false; flatLayout = newValue; safeRefresh(); } else if (event.getProperty().equals(ARESPreferences.SHOW_CATEGORY)) { boolean newValue = ((Boolean) event.getNewValue()).booleanValue() ? true : false; showCategory = newValue; safeRefresh(); } } }; ARESUI.INSTANCE.getPreferenceStore().addPropertyChangeListener(propertyListener); elementListener = new IARESElementChangeListener() { // 2012-03-08 sundl ���Ӳ��� public void elementChanged(ARESElementChangedEvent event) { safeRefresh(); } }; if (refresh) ARESCore.addElementListener(elementListener); } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { this.viewer = (TreeViewer)viewer; this.input = newInput; super.inputChanged(viewer, oldInput, newInput); } public Object[] getChildren(Object parentElement) { if (parentElement instanceof ARESResourceCategory) { ARESResourceCategory category = (ARESResourceCategory)parentElement; return getCategoryChildren(category); } else if (parentElement instanceof ResGroup) { return getGroupChildren((ResGroup) parentElement); } else if (parentElement instanceof RefLibContainer) { return ((RefLibContainer) parentElement).getChildren(); } else if (parentElement instanceof IAdaptable) { IWorkbenchAdapter adapter = (IWorkbenchAdapter) ((IAdaptable) parentElement).getAdapter(IWorkbenchAdapter.class); if (adapter != null) return adapter.getChildren(parentElement); } return super.getChildren(parentElement); } @Override protected Object[] getProjectChildren(IARESProject project) { if (project instanceof IARESProject) { //return getModuleRoots((ICommonProject)project); try { List<Object> children = new ArrayList<Object>(); for ( IARESElement child : ((IARESProject)project).getChildren()) { if (!(child instanceof IReferencedLibrary) ){ children.add(child); } } // 2013-05-15 sundl ֻ����ref nature��������ýڵ� // ע��������߼���Ϊ�����Ϲ��̵ļ����ԣ���ref nature�IJ���ʾ���ýڵ㣻��ref nature�IJ���ʾ���ýڵ� if (!ARESProject.hasRefNature(project.getProject())) children.add(new RefLibContainer((IARESProject) project)); return children.toArray(); } catch (ARESModelException e) { //e.printStackTrace(); } } return NO_CHILDREN; } protected IARESModuleRoot[] getModuleRoots(IARESProject project) { List<IARESModuleRoot> roots = new ArrayList<IARESModuleRoot>(); try { roots.addAll(Arrays.asList(project.getModuleRoots())); } catch (ARESModelException e) { e.printStackTrace(); } return roots.toArray(new IARESModuleRoot[roots.size()]); } protected Object[] getModuleRootChildren(IARESModuleRoot root) throws ARESModelException { ModulesRootTypeRegistry reg = ModulesRootTypeRegistry.getInstance(); IModuleRootDescriptor desc = reg.getModuleRootDescriptor(root.getType()); List<IARESElement> results = new ArrayList<IARESElement>(); // ��������˲���ʾĬ��ģ�� if (desc != null && !desc.useDefaultModule()) { IARESResource[] resUnderDefaultModule = root.getModule("").getARESResources(); List<IARESModule> allModules = new ArrayList<IARESModule>(Arrays.asList(getModules(root))); allModules.remove(root.getModule("")); results.addAll(Arrays.asList(resUnderDefaultModule)); results.addAll(allModules); // ����ʾĬ��ģ�飬ģ������Ի���Ϊһ��Ĭ��ģ���µ���Դ�������������resUnderDefaultModule����Բ������⴦�� } else { results.addAll(Arrays.asList(getModules(root))); // ģ���������������ģ��������root.xml����, ����ļ��ڽ�����ʱ�򣬱�������ΪĬ��ģ���µ�һ����ͨ��Դ if ((desc != null) && desc.useProperty()) { IARESModule defModule = root.getModule(StringUtils.EMPTY); IARESResource profile = defModule.getARESResource(IARESModuleRoot.PROPERTY_FILE); if (profile != null && profile.exists()) { results.add(profile); } } } return (IARESElement[]) results.toArray(new IARESElement[results.size()]); } private IARESModule[] getModules(IARESModuleRoot root) throws ARESModelException { if (flatLayout) { return root.getModules(); } else { List<IARESModule> children = new ArrayList<IARESModule>(); getHierarchicalModuleChildren(root, null, children); return children.toArray(new IARESModule[0]); } } // ����㼶ģʽ��ģ�����ģ�� @SuppressWarnings("unchecked") private void getHierarchicalModuleChildren(IARESModuleRoot root, IARESModule fragment, Collection result) throws ARESModelException { IARESElement[] children = root.getChildren(); String prefix= fragment != null ? fragment.getElementName() + '.' : ""; //$NON-NLS-1$ int prefixLen= prefix.length(); for (int i= 0; i < children.length; i++) { IARESModule curr= (IARESModule) children[i]; String name= curr.getElementName(); if (name.startsWith(prefix) && name.length() > prefixLen && name.indexOf('.', prefixLen) == -1) { result.add(curr); } else if (fragment == null && curr.isDefaultModule()) { result.add(curr); } } } // ģ���getChildren protected Object[] getModuleChildren(IARESModule module) throws ARESModelException { if (flatLayout) { return getNonModuleChildrenOfModule(module); } else { List<Object> children = new ArrayList<Object>(); getHierarchicalModuleChildren((IARESModuleRoot)module.getParent(), module, children); children.addAll(Arrays.asList(getNonModuleChildrenOfModule(module))); return children.toArray(); } } private Object[] getNonModuleChildrenOfModule(IARESModule module) { if (showCategory) { // �ȼ���Ӧ����ʾ�ķ��� ARESResourceCategory[] cates = getCategories(module); // ������Щû��ע��������Դ���ͣ�ֱ����ʾ��ģ���� List<String> nonCateTypes = ARESResRegistry.getInstance().getNonCategoryResTypes(); IARESResource[] nonCateResources = module.getARESResources(nonCateTypes.toArray(new String[0])); if (nonCateResources.length > 0) { Object[] result = new Object[cates.length + nonCateResources.length]; System.arraycopy(cates, 0, result, 0, cates.length); System.arraycopy(nonCateResources, 0, result, cates.length, nonCateResources.length); return result; } else if (cates.length > 0) { return cates; } else { return new Object[0]; } } else { if (showGroup) { List<Object> children = new ArrayList<Object>(); children.addAll(ResGroup.getGroups(module)); children.addAll(ResGroup.getNoGroupResources(module)); return children.toArray(); } else { return module.getARESResources(); } } } protected ARESResourceCategory[] getCategories(IARESModule module) { ARESResourceCategory[] cates = catesMap.get(module); if (cates == null) { cates = createCategories(module); catesMap.put(module, cates); } return cates; } /** * ���㲢����ģ���µķ��� * @param module ģ�� * @return ģ���µķ��� */ private ARESResourceCategory[] createCategories(IARESModule module) { String rootType = module.getRoot().getType(); ARESResRegistry reg = ARESResRegistry.getInstance(); ModuleRootType2ResTypeMap map = ModuleRootType2ResTypeMap.getInstance(); Set<ARESResourceCategory> cates = new HashSet<ARESResourceCategory>(); IResCategoryDescriptor[] allRegistedCates = reg.getCategories(); for (IResCategoryDescriptor desc : allRegistedCates) { // ��������ע��ķ��ֻ࣬Ҫ����ע�����Դ������һ�����ڸ�ģ���������ŵģ�����ʾ���� for (String type : reg.getRestypes(desc.getId())) { if (map.isAllowed(rootType, type)) { cates.add(new ARESResourceCategory(module, desc.getId())); break; } } } return cates.toArray(new ARESResourceCategory[0]); } protected Object[] getCategoryChildren(ARESResourceCategory category) { IARESResource[] resources = category.getResources(); if (showGroup) { List<Object> children = new ArrayList<Object>(); IARESResource[] resource = category.getResources(); Set<ResGroup> groups = ResGroup.getGroups(resource); for (ResGroup g : groups) { g.setCateId(category.getId()); } children.addAll(groups); children.addAll(ResGroup.getNoGroupResources(resources)); return children.toArray(); } return resources; } protected Object[] getGroupChildren(ResGroup group) { return group.getResources(); } public boolean hasChildren(Object element) { if (element instanceof IARESModule || element instanceof ARESResourceCategory) { return getChildren(element).length > 0; } else if (element instanceof RefLibContainer) { return ((RefLibContainer) element).getChildren().length > 0; } return super.hasChildren(element); } @Override protected Object internalGetParent(Object child) { if (!flatLayout && child instanceof IARESModule) { return getHierarchicalModuleParent((IARESModule)child); } if (child instanceof ARESResourceCategory) { return ((ARESResourceCategory)child).getModule(); } if (child instanceof ResGroup) { ResGroup group = (ResGroup) child; if (group.getCateId() != null) { } } if (child instanceof IARESResource) { IARESResource res = (IARESResource) child; Object parent = null; if (showCategory) { // �����Դ�з��࣬�򷵻ط��� parent = getCategoryOfResoruce(res); } if (parent != null) { ARESResourceCategory cate = (ARESResourceCategory) parent; if (showGroup) { String group = ARESElementUtil.getGroup(res); if (StringUtils.isNotEmpty(group)) { parent = new ResGroup(group, res.getModule(), cate.getId()); } } return parent; } else { if (showGroup) { String group = ARESElementUtil.getGroup(res); return new ResGroup(group, res.getModule()); } return res.getModule(); } } else if (child instanceof RefLibContainer) { return ((RefLibContainer) child).getProject(); } else if (child instanceof IReferencedLibrary) { return new RefLibContainer(((IReferencedLibrary) child).getARESProject()); } return super.internalGetParent(child); } public ARESResourceCategory getCategoryOfResoruce(IARESResource res) { IARESModule module = res.getModule(); ARESResourceCategory[] cates = getCategories(module); for (ARESResourceCategory cate : cates) { if (cate.isResTypeAllowed(res.getType())) return cate; } return null; } public static Object getHierarchicalModuleParent(IARESModule module) { String name= module.getElementName(); IARESModuleRoot parent= (IARESModuleRoot) module.getParent(); int index= name.lastIndexOf('.'); if (index != -1) { String realParentName= name.substring(0, index); IARESModule element= parent.getModule(realParentName); if (element != null && element.exists()) { return element; } } return parent; } protected void refresh() { if (viewer.getControl().isDisposed()) return; viewer.getTree().setRedraw(false); viewer.refresh(); viewer.getTree().setRedraw(true); } public void safeRefresh() { if (viewer == null) return; Control ctrl = viewer.getTree(); if (!ctrl.isDisposed()) { if (ctrl.getDisplay().getThread() == Thread.currentThread()) { refresh(); } else { viewer.getTree().getDisplay().asyncExec(new Runnable() { public void run() { refresh(); } }); } } } @Override public void dispose() { super.dispose(); ARESCore.removeElementListener(elementListener); ARESUI.getDefault().getPreferenceStore().removePropertyChangeListener(propertyListener); } }