/******************************************************************************* * Copyright (c) 2012-2015 Codenvy, S.A. * 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: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.jdt.search; import org.eclipse.che.dto.server.DtoFactory; import org.eclipse.che.ide.ext.java.shared.dto.model.ClassFile; import org.eclipse.che.ide.ext.java.shared.dto.model.CompilationUnit; import org.eclipse.che.ide.ext.java.shared.dto.model.Field; import org.eclipse.che.ide.ext.java.shared.dto.model.ImportDeclaration; import org.eclipse.che.ide.ext.java.shared.dto.model.Initializer; import org.eclipse.che.ide.ext.java.shared.dto.model.JavaProject; import org.eclipse.che.ide.ext.java.shared.dto.model.Method; import org.eclipse.che.ide.ext.java.shared.dto.model.PackageFragment; import org.eclipse.che.ide.ext.java.shared.dto.model.PackageFragmentRoot; import org.eclipse.che.ide.ext.java.shared.dto.model.Type; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.jdt.core.IClassFile; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IField; import org.eclipse.jdt.core.IImportContainer; import org.eclipse.jdt.core.IImportDeclaration; import org.eclipse.jdt.core.IInitializer; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.ITypeRoot; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.ui.JavaElementLabels; import org.eclipse.jdt.ui.StandardJavaElementContentProvider; import org.eclipse.search.ui.text.AbstractTextSearchResult; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; /** * Helper class for converting <code>IJavaElement</code> to DTO. * * @author Evgen Vidolob */ public class JavaElementToDtoConverter { public static final int LEVEL_TYPE = 1; public static final int LEVEL_FILE = 2; public static final int LEVEL_PACKAGE = 3; public static final int LEVEL_PROJECT = 4; private static final int[][] JAVA_ELEMENT_TYPES = {{IJavaElement.TYPE}, {IJavaElement.CLASS_FILE, IJavaElement.COMPILATION_UNIT}, {IJavaElement.PACKAGE_FRAGMENT}, {IJavaElement.JAVA_PROJECT, IJavaElement.PACKAGE_FRAGMENT_ROOT}, {IJavaElement.JAVA_MODEL}}; private static final int[][] RESOURCE_TYPES = {{}, {IResource.FILE}, {IResource.FOLDER}, {IResource.PROJECT}, {IResource.ROOT}}; private static final int MAX_LEVEL = JAVA_ELEMENT_TYPES.length - 1; private final FastJavaElementProvider contentProvider; private Map<Object, Set<Object>> childrens = new HashMap<>(); private int level; private AbstractTextSearchResult result; public JavaElementToDtoConverter(AbstractTextSearchResult result) { this.result = result; contentProvider = new FastJavaElementProvider(); level = LEVEL_PROJECT; } public void addElementToProjectHierarchy(IJavaElement element) { insert(null, null, element); } private Object internalGetParent(Object child) { return contentProvider.getParent(child); } private Object getParent(Object child) { Object possibleParent = internalGetParent(child); if (possibleParent instanceof IJavaElement) { IJavaElement javaElement = (IJavaElement)possibleParent; for (int j = level; j < MAX_LEVEL + 1; j++) { for (int i = 0; i < JAVA_ELEMENT_TYPES[j].length; i++) { if (javaElement.getElementType() == JAVA_ELEMENT_TYPES[j][i]) { return null; } } } } else if (possibleParent instanceof IResource) { IResource resource = (IResource)possibleParent; for (int j = level; j < MAX_LEVEL + 1; j++) { for (int i = 0; i < RESOURCE_TYPES[j].length; i++) { if (resource.getType() == RESOURCE_TYPES[j][i]) { return null; } } } } return possibleParent; } private void insert(Map<Object, Set<Object>> toAdd, Set<Object> toUpdate, Object child) { Object parent = getParent(child); while (parent != null) { if (insertChild(parent, child)) { if (toAdd != null) insertInto(parent, child, toAdd); } else { if (toUpdate != null) toUpdate.add(parent); return; } child = parent; parent = getParent(child); } if (insertChild(result, child)) { if (toAdd != null) insertInto(result, child, toAdd); } } private boolean insertChild(Object parent, Object child) { return insertInto(parent, child, childrens); } private boolean insertInto(Object parent, Object child, Map<Object, Set<Object>> map) { Set<Object> children = map.get(parent); if (children == null) { children = new HashSet<>(); map.put(parent, children); } return children.add(child); } public List<JavaProject> getProjects() throws JavaModelException { Set<Object> objects = childrens.get(result); List<JavaProject> result = new ArrayList<>(); if (objects == null) { return result; } for (Object object : objects) { JavaProject javaProject = DtoFactory.newDto(JavaProject.class); IJavaProject project = (IJavaProject)object; javaProject.setName(project.getElementName()); String path = project.getPath().toOSString(); javaProject.setPath(path); javaProject.setPackageFragmentRoots(getPackageFragmentRoots(object, path)); result.add(javaProject); } return result; } private List<PackageFragmentRoot> getPackageFragmentRoots(Object parent, String projectPath) throws JavaModelException { List<PackageFragmentRoot> result = new ArrayList<>(); Set<Object> objects = childrens.get(parent); if (objects == null) { return result; } for (Object object : objects) { if (object instanceof IPackageFragmentRoot) { PackageFragmentRoot root = DtoFactory.newDto(PackageFragmentRoot.class); IPackageFragmentRoot fragmentRoot = (IPackageFragmentRoot)object; root.setProjectPath(projectPath); root.setKind(fragmentRoot.getKind()); root.setPath(fragmentRoot.getPath().toOSString()); root.setElementName(fragmentRoot.getElementName()); root.setHandleIdentifier(fragmentRoot.getHandleIdentifier()); root.setPackageFragments(getPackageFragments(fragmentRoot, projectPath)); result.add(root); } } return result; } private List<PackageFragment> getPackageFragments(IPackageFragmentRoot parent, String projectPath) throws JavaModelException { List<PackageFragment> result = new ArrayList<>(); Set<Object> objects = childrens.get(parent); if (objects == null) { return result; } for (Object object : objects) { if (object instanceof IPackageFragment) { IPackageFragment packageFragment = (IPackageFragment)object; PackageFragment fragment = DtoFactory.newDto(PackageFragment.class); fragment.setProjectPath(projectPath); fragment.setPath(packageFragment.getPath().toOSString()); fragment.setHandleIdentifier(packageFragment.getHandleIdentifier()); fragment.setElementName(packageFragment.getElementName()); fragment.setKind(packageFragment.getKind()); fragment.setDefaultPackage(packageFragment.isDefaultPackage()); List<CompilationUnit> compilationUnits = new ArrayList<>(); List<ClassFile> classFiles = new ArrayList<>(); addCompilationUnitsAndClassFiles(object, compilationUnits, classFiles); fragment.setCompilationUnits(compilationUnits); fragment.setClassFiles(classFiles); result.add(fragment); } } return result; } private void addCompilationUnitsAndClassFiles(Object parent, List<CompilationUnit> compilationUnits, List<ClassFile> classFiles) throws JavaModelException { Set<Object> childrens = this.childrens.get(parent); for (Object children : childrens) { if (children instanceof ICompilationUnit) { ICompilationUnit unit = (ICompilationUnit)children; CompilationUnit compilationUnit = DtoFactory.newDto(CompilationUnit.class); compilationUnit.setElementName(unit.getElementName()); compilationUnit.setProjectPath(unit.getJavaProject().getPath().toOSString()); compilationUnit.setPath(unit.getResource().getFullPath().toOSString()); compilationUnit.setHandleIdentifier(unit.getHandleIdentifier()); compilationUnit.setLabel(JavaElementLabels.getElementLabel(unit, JavaElementLabels.ALL_DEFAULT)); compilationUnit.setImports(getImports(children)); compilationUnit.setTypes(getTypes(children)); compilationUnits.add(compilationUnit); } else if (children instanceof IClassFile) { ClassFile classFile = DtoFactory.newDto(ClassFile.class); IClassFile clazz = (IClassFile)children; classFile.setHandleIdentifier(clazz.getHandleIdentifier()); classFile.setElementName(clazz.getElementName()); classFile.setPath(clazz.getType().getFullyQualifiedName()); classFile.setLabel(JavaElementLabels.getElementLabel(clazz, JavaElementLabels.ALL_DEFAULT)); classFile.setProjectPath(clazz.getJavaProject().getPath().toOSString()); classFile.setType(getTypes(children).get(0)); classFiles.add(classFile); } } } private List<ImportDeclaration> getImports(Object parent) throws JavaModelException { List<ImportDeclaration> result = new ArrayList<>(); Set<Object> objects = childrens.get(parent); if (objects == null) { return result; } for (Object object : objects) { if (object instanceof IImportContainer) { Set<Object> imports = childrens.get(object); if (imports == null) { continue; } addImport(result, imports); } } return result; } private void addImport(List<ImportDeclaration> result, Set<Object> imports) throws JavaModelException { for (Object im : imports) { if (im instanceof IImportDeclaration) { IImportDeclaration dec = (IImportDeclaration)im; ImportDeclaration importDeclaration = DtoFactory.newDto(ImportDeclaration.class); importDeclaration.setFlags(dec.getFlags()); importDeclaration.setHandleIdentifier(dec.getHandleIdentifier()); importDeclaration.setElementName(dec.getElementName()); result.add(importDeclaration); } } } private List<Type> getTypes(Object parent) throws JavaModelException { List<Type> result = new ArrayList<>(); Set<Object> objects = childrens.get(parent); if (objects == null) { return result; } for (Object object : objects) { if (object instanceof IType) { IType type = (IType)object; Type dtoType = DtoFactory.newDto(Type.class); dtoType.setElementName(type.getElementName()); dtoType.setLabel(JavaElementLabels.getElementLabel(type, JavaElementLabels.ALL_DEFAULT)); dtoType.setHandleIdentifier(type.getHandleIdentifier()); dtoType.setFlags(type.getFlags()); dtoType.setTypes(getTypes(object)); dtoType.setFields(getFields(object)); dtoType.setMethods(getMethods(object)); dtoType.setInitializers(getInitializes(object)); if (parent instanceof ITypeRoot) { IType primaryType = ((ITypeRoot)parent).findPrimaryType(); dtoType.setPrimary(type.equals(primaryType)); } else { dtoType.setPrimary(false); } result.add(dtoType); } } return result; } private List<Initializer> getInitializes(Object parent) throws JavaModelException { List<Initializer> result = new ArrayList<>(); Set<Object> objects = childrens.get(parent); if (objects == null) { return result; } for (Object object : objects) { if (object instanceof IInitializer) { IInitializer initializer = (IInitializer)object; Initializer init = DtoFactory.newDto(Initializer.class); init.setElementName(initializer.getElementName()); init.setHandleIdentifier(initializer.getHandleIdentifier()); init.setFlags(initializer.getFlags()); init.setLabel(JavaElementLabels.getElementLabel(initializer, JavaElementLabels.ALL_DEFAULT)); result.add(init); } } return result; } private List<Method> getMethods(Object parent) throws JavaModelException { List<Method> result = new ArrayList<>(); Set<Object> objects = childrens.get(parent); if (objects == null) { return result; } for (Object object : objects) { if (object instanceof IMethod) { IMethod method = (IMethod)object; Method met = DtoFactory.newDto(Method.class); met.setHandleIdentifier(method.getHandleIdentifier()); met.setFlags(method.getFlags()); met.setElementName(method.getElementName()); met.setLabel(JavaElementLabels.getElementLabel(method, JavaElementLabels.ALL_DEFAULT)); result.add(met); } } return result; } private List<Field> getFields(Object parent) throws JavaModelException { List<Field> result = new ArrayList<>(); Set<Object> objects = childrens.get(parent); if (objects == null) { return result; } for (Object object : objects) { if (object instanceof IField) { IField iField = (IField)object; Field field = DtoFactory.newDto(Field.class); field.setElementName(iField.getElementName()); field.setHandleIdentifier(iField.getHandleIdentifier()); field.setFlags(iField.getFlags()); field.setLabel(JavaElementLabels.getElementLabel(iField, JavaElementLabels.ALL_DEFAULT)); result.add(field); } } return result; } static class FastJavaElementProvider extends StandardJavaElementContentProvider { @Override public Object getParent(Object element) { Object parent = internalGetParent(element); if (parent == null && element instanceof IAdaptable) { IAdaptable adaptable = (IAdaptable)element; Object javaElement = adaptable.getAdapter(IJavaElement.class); if (javaElement != null) { parent = internalGetParent(javaElement); } else { Object resource = adaptable.getAdapter(IResource.class); if (resource != null) { parent = internalGetParent(resource); } } } return parent; } } }