package org.jboss.tools.seam.internal.core;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.jboss.tools.common.model.project.ext.event.Change;
import org.jboss.tools.seam.core.ISeamComponent;
import org.jboss.tools.seam.core.ISeamElement;
import org.jboss.tools.seam.core.ISeamPackage;
public class SeamPackageUtil {
public static List<Change> revalidatePackages(ISeamElement parent, Map<String,SeamComponent> allComponents, Collection<ISeamComponent> components, Map<String,ISeamPackage> packages) {
List<Change> changes = null;
changes = checkPackages(allComponents, packages, changes);
changes = fillPackages(parent, packages, components, changes);
changes = cleanPackages(parent, packages, changes);
return changes;
}
static List<Change> checkPackages(Map<String,SeamComponent> allComponents, Map<String,ISeamPackage> packages, List<Change> changes) {
for (ISeamPackage p : packages.values()) {
Iterator<ISeamComponent> cs = p.getComponents().iterator();
while(cs.hasNext()) {
ISeamComponent c = cs.next();
String pkg = getPackageName(c);
if(allComponents.get(c.getName()) == null || !p.getQualifiedName().equals(pkg)) {
cs.remove();
changes = Change.addChange(changes, new Change(p, null, c, null));
}
}
changes = checkPackages(allComponents, p.getPackages(), changes);
}
return changes;
}
static List<Change> fillPackages(ISeamElement parent, Map<String,ISeamPackage> packages, Collection<ISeamComponent> components, List<Change> changes) {
for (ISeamComponent c : components) {
String pkg = getPackageName(c);
ISeamPackage p = findOrCreatePackage(parent, packages, pkg);
if(p.getComponents().contains(c)) continue;
p.getComponents().add(c);
changes = Change.addChange(changes, new Change(p, null, null, c));
}
return changes;
}
static List<Change> cleanPackages(ISeamElement parent, Map<String,ISeamPackage> packages, List<Change> changes) {
Iterator<String> ps = packages.keySet().iterator();
while(ps.hasNext()) {
ISeamPackage p = packages.get(ps.next());
changes = cleanPackages(p, p.getPackages(), changes);
if(p.getComponents().size() == 0 && p.getPackages().size() == 0) {
ps.remove();
changes = Change.addChange(changes, new Change(parent, null, p, null));
}
}
return changes;
}
static String getPackageName(ISeamComponent c) {
// Package name can be based
// 1) on qualified java class name,
// then it is java package name
// 2) on seam component name,
// then name is processed by analogy with java,
// and package name is its part until the last dot.
// Presently, only second approach is implemented,
// in future an option can be added, that
// will allow user to customize view by selecting
// the 'kind' of packages.
String cls = c.getName();
//c.getClassName();
if(cls == null || cls.length() == 0) {
return "(unspecified)"; //$NON-NLS-1$
} else if(cls.startsWith("${") || cls.startsWith("#{")) { //$NON-NLS-1$ //$NON-NLS-2$
return "(specified with EL)"; //$NON-NLS-1$
} else {
int d = cls.lastIndexOf('.');
return (d < 0) ? "(default package)" : cls.substring(0, d); //$NON-NLS-1$
}
}
static ISeamPackage findPackage(ISeamElement parent, Map<String, ISeamPackage> packages, String qualifiedName) {
return findOrCreatePackage(parent, packages, qualifiedName, false);
}
static ISeamPackage findOrCreatePackage(ISeamElement parent, Map<String, ISeamPackage> packages, String qualifiedName) {
return findOrCreatePackage(parent, packages, qualifiedName, true);
}
static ISeamPackage findOrCreatePackage(ISeamElement parent, Map<String, ISeamPackage> packages, String qualifiedName, boolean create) {
int i = qualifiedName.indexOf('.');
String firstName = i < 0 ? qualifiedName : qualifiedName.substring(0, i);
String tail = i < 0 ? null : qualifiedName.substring(i + 1);
ISeamPackage p = packages.get(firstName);
if(p == null) {
if(!create) return null;
SeamPackage pi = new SeamPackage(firstName);
pi.setParent(parent);
pi.setSourcePath(parent.getSourcePath());
p = pi;
packages.put(firstName, pi);
}
return (tail != null) ? findOrCreatePackage(p, p.getPackages(), tail) : p;
}
public static void collectAllPackages(Map<String, ISeamPackage> packages, Collection<ISeamPackage> list) {
for (ISeamPackage p : packages.values()) {
if(!p.getComponents().isEmpty()) list.add(p);
collectAllPackages(p.getPackages(), list);
}
}
}