/******************************************************************************* * Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is 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: * Exadel, Inc. and Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.common.model.util; import java.util.*; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.IParent; import org.eclipse.jdt.core.JavaModelException; import org.jboss.tools.common.model.*; import org.jboss.tools.common.model.filesystems.FileSystemsHelper; import org.jboss.tools.common.model.filesystems.XFileObject; import org.jboss.tools.common.model.plugin.ModelPlugin; public class AccessibleClasses implements ISimpleTree { private static final int JAVA = 1; private static final int PROJECT = 2; private int mode = 2; private XModel model; IJavaProject javaProject; private Map<String,SortedSet<String>> map = null; private static SortedSet<String> EMPTY = new TreeSet<String>(); private Comparator<String> comparator = new ACComparator<String>(); public AccessibleClasses(XModel model, boolean useproject) { this(model, (useproject && model != null) ? 3 : 1); } protected XModel getModel() { return model; } public AccessibleClasses(XModel model, int mode) { this.model = (XModel)model; javaProject = EclipseResourceUtil.getJavaProject(EclipseResourceUtil.getProject(model.getRoot())); this.mode = mode; map = ((mode & PROJECT) != 0) ? new HashMap<String,SortedSet<String>>() : null; } public String[] getContent(String packagename) { if(map == null) return AccessibleJava.getInstance().getContent(packagename); SortedSet<String> o = map.get(packagename); if(o == null) { load(packagename); o = map.get(packagename); } if(o == EMPTY) return null; String[] r = o.toArray(new String[o.size()]); Arrays.sort(r, comparator); return r; } protected void load(String packagename) { SortedSet<String> list = new TreeSet<String>(); String[] s = ((mode & JAVA) == 0) ? null : AccessibleJava.getInstance().getContent(packagename); if(s != null) for (int i = 0; i < s.length; i++) list.add(s[i]); boolean exists = buildPackage(list, packagename); if(s == null && !exists) { map.put(packagename, EMPTY); } else { map.put(packagename, list); } } private static String exts = ".class.bo.java.cls."; //$NON-NLS-1$ protected String extensions() { return exts; } private boolean buildPackage(SortedSet<String> list, String packagename) { String pkg = packagename.toLowerCase(); if(pkg.endsWith(".cvs")) return false; //$NON-NLS-1$ if(pkg.endsWith(".svn")) return false; //$NON-NLS-1$ boolean exists = false; XModelObject fs = FileSystemsHelper.getFileSystems(model); if(fs == null) return false; try { exists = getChildren(list, packagename); } catch (JavaModelException e) { ModelPlugin.getPluginLog().logError(e); } return exists; } private boolean getChildren(SortedSet<String> list, String packagename) throws JavaModelException { if(javaProject == null || !javaProject.exists()) return false; boolean exists = false; boolean r = "%root%".equals(packagename); //$NON-NLS-1$ String jp = (r) ? "" : packagename; //$NON-NLS-1$ IPackageFragmentRoot[] rs = javaProject.getPackageFragmentRoots(); for (int i = 0; i < rs.length; i++) { IParent pf = (r) ? rs[i] : rs[i].getPackageFragment(packagename); if(pf == null || !((IJavaElement)pf).exists()) continue; exists = true; IJavaElement[] cs = pf.getChildren(); process(list, cs, jp); if(!r) process2(list, rs[i].getChildren(), jp); } return exists; } private void process(SortedSet<String> list, IJavaElement[] cs, String jp) throws JavaModelException { for (int j = 0; j < cs.length; j++) { boolean isp = cs[j] instanceof IPackageFragment; String n = cs[j].getElementName(); if(n.length() == 0 && isp) { process(list, ((IPackageFragment)cs[j]).getChildren(), jp); } else { if(isp) { if(n.indexOf('.') >= 0) continue; n += "."; //$NON-NLS-1$ } else { int d = n.lastIndexOf('.'); if(d >= 0) { String ext = n.substring(d + 1); n = n.substring(0, d); if(!extensions().contains("." + ext + ".")) continue; //$NON-NLS-1$ //$NON-NLS-2$ } } if(accepts(jp, n)) { list.add(n); } } } } private void process2(SortedSet<String> list, IJavaElement[] cs, String jp) throws JavaModelException { for (int j = 0; j < cs.length; j++) { String n = cs[j].getElementName(); if(!n.startsWith(jp + ".")) continue; //$NON-NLS-1$ n = n.substring(jp.length() + 1); boolean isp = cs[j] instanceof IPackageFragment; if(isp) { if(n.indexOf('.') >= 0) continue; n += "."; //$NON-NLS-1$ } else { int d = n.lastIndexOf('.'); if(d >= 0) { String ext = n.substring(d + 1); n = n.substring(0, d); if(!extensions().contains("." + ext + ".")) continue; //$NON-NLS-1$ //$NON-NLS-2$ } } if(accepts(jp, n)) { list.add(n); } } } protected boolean accepts(String packagename, String n) { return !n.equalsIgnoreCase("CVS.") && !n.equalsIgnoreCase("svn."); //$NON-NLS-1$ //$NON-NLS-2$ } } class ACComparator<T> implements Comparator<T> { public int compare(Object o1, Object o2) { String s1 = (String)o1; String s2 = (String)o2; if(s1.endsWith(".") && !s2.endsWith(".")) return -1; //$NON-NLS-1$ //$NON-NLS-2$ if(s2.endsWith(".") && !s1.endsWith(".")) return 1; //$NON-NLS-1$ //$NON-NLS-2$ return s1.compareToIgnoreCase(s2); } public boolean equals(Object obj) { return this == obj; } }