/******************************************************************************* * 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.project; import java.io.File; import java.util.*; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.*; import org.eclipse.jdt.core.*; import org.jboss.tools.common.meta.action.*; import org.jboss.tools.common.model.*; import org.jboss.tools.common.model.filesystems.FileSystemsHelper; import org.jboss.tools.common.model.filesystems.impl.FileSystemsLoader; import org.jboss.tools.common.model.plugin.ModelPlugin; import org.jboss.tools.common.model.project.IModelNature; import org.jboss.tools.common.model.util.*; public class ClassPathUpdate { IProject project = null; IJavaProject javaProject; XModel model; List<IClasspathEntry> newClassPath; IPath classes; Map<String,String> replacedSrc = new HashMap<String,String>(); public void setProject(IProject project) { this.project = project; } public void setModel(XModel model) { String entity = model.getRoot().getModelEntity().getName(); if("RootDummy".equals(entity)) { //$NON-NLS-1$ String pn = (project == null) ? "?" : project.getName(); //$NON-NLS-1$ throw new IllegalStateException("Project " + pn + " is corrupted."); //$NON-NLS-1$ //$NON-NLS-2$ } this.model = model; } public XModel getModel() { return model; } public void setReplacedSrc(Map<String,String> replacedSrc) { this.replacedSrc = replacedSrc; } public void setClasses(IPath classes) { this.classes = classes; } public void execute() throws CoreException { if(model == null) { IModelNature nature = (IModelNature)EclipseResourceUtil.getModelNature(project); setModel(nature.getModel()); } javaProject = JavaCore.create(project); EclipseResourceUtil.addNatureToProject(project, JavaCore.NATURE_ID); init(); createOutputFolder(); removeReplacedSrc(); createSrcFolders(); createClassPath(); commit(); } private void init() throws CoreException { newClassPath = new ArrayList<IClasspathEntry>(Arrays.asList(javaProject.getRawClasspath())); Iterator iterator = newClassPath.iterator(); while (iterator.hasNext()) { IClasspathEntry entry = (IClasspathEntry)iterator.next(); if (project.getFullPath().equals(entry.getPath())) iterator.remove(); } } private void commit() throws CoreException { removeDuplicateEntries(); IClasspathEntry[] entries = (IClasspathEntry[])newClassPath.toArray(new IClasspathEntry[newClassPath.size()]); if(entries.length != 0) { javaProject.setRawClasspath(entries, new NullProgressMonitor()); } } public void revalidateLibs(XModel model) throws XModelException, CoreException { setProject(EclipseResourceUtil.getProject(model.getRoot())); setModel(model); javaProject = JavaCore.create(project); init(); addLibJars(); commit(); } private void removeReplacedSrc() { if(replacedSrc == null || replacedSrc.isEmpty()) return; String[] s = (String[])replacedSrc.keySet().toArray(new String[0]); for (int i = 0; i < s.length; i++) { IClasspathEntry entry = createNewClasspathEntry(s[i], IClasspathEntry.CPE_SOURCE); int i1 = newClassPath.indexOf(entry); if(i1 < 0) continue; String sn = (String)replacedSrc.get(s[i]); if(sn == null || sn.length() == 0) { newClassPath.remove(i1); } else { entry = createNewClasspathEntry(sn, IClasspathEntry.CPE_SOURCE); int i2 = newClassPath.indexOf(entry); if(i2 < 0) newClassPath.set(i1, entry); else newClassPath.remove(i1); } } } private void createSrcFolders() { XModelObject web = model.getByPath("Web"); //$NON-NLS-1$ if(web == null) return; XModelObject[] children = model.getByPath("Web").getChildren(); //$NON-NLS-1$ List<String> srcPaths = new ArrayList<String>(); Set<String> set = new HashSet<String>(); for (int i = 0; i < children.length; i++) { String objectPaths = children[i].getAttributeValue("src file system"/*WebModuleConstants.ATTR_SRC_FS*/); //$NON-NLS-1$ if(objectPaths == null || objectPaths.length() == 0) continue; StringTokenizer st = new StringTokenizer(objectPaths, ",;"); //$NON-NLS-1$ while(st.hasMoreTokens()) { String objectPath = st.nextToken().trim(); if(objectPath.length() == 0) continue; XModelObject srcObject = model.getByPath("FileSystems/" + objectPath); //$NON-NLS-1$ if (srcObject == null) continue; String osPath = XModelObjectUtil.getExpandedValue(srcObject, XModelObjectConstants.ATTR_NAME_LOCATION, null); if (osPath != null && !"".equals(osPath) && !set.contains(osPath)) { //$NON-NLS-1$ srcPaths.add(osPath); set.add(osPath); } } } children = FileSystemsHelper.getFileSystems(model).getChildren("FileSystemFolder"); for (XModelObject c: children) { String n = c.getAttributeValue(XModelObjectConstants.ATTR_NAME); if("src".equals(n) || n.startsWith("src-")) { String osPath = XModelObjectUtil.getExpandedValue(c, XModelObjectConstants.ATTR_NAME_LOCATION, null); if (osPath != null && !"".equals(osPath) && !set.contains(osPath)) { //$NON-NLS-1$ srcPaths.add(osPath); set.add(osPath); } } } Iterator iterator = srcPaths.iterator(); while (iterator.hasNext()) { IClasspathEntry entry = createNewClasspathEntry(iterator.next().toString(), IClasspathEntry.CPE_SOURCE); insertSrc(entry); } } private void insertSrc(IClasspathEntry entry) { if(!entryAlreadyExists(entry, newClassPath)) newClassPath.add(0, entry); } private void createOutputFolder() { XModelObject classesObject = model.getByPath("FileSystems/classes"); //$NON-NLS-1$ String classesPath = ""; //$NON-NLS-1$ if (classesObject != null) classesPath = XModelObjectUtil.getExpandedValue(classesObject, XModelObjectConstants.ATTR_NAME_LOCATION, null); else if(classes != null) classesPath = classes.toString(); try { javaProject.setOutputLocation( EclipseResourceUtil.getRelativePath(project, classesPath), new NullProgressMonitor() ); } catch(JavaModelException ex) { ModelPlugin.getPluginLog().logError(ex); } } private void removeDuplicateEntries() { List<IClasspathEntry> removeList = new ArrayList<IClasspathEntry>(); List<IClasspathEntry> tmpList = new ArrayList<IClasspathEntry>(); Iterator<IClasspathEntry> iterator = newClassPath.iterator(); while (iterator.hasNext()) { IClasspathEntry entry = (IClasspathEntry)iterator.next(); tmpList.clear(); tmpList.addAll(newClassPath); tmpList.remove(entry); if (entryAlreadyExists(entry, tmpList)) removeList.add(entry); } iterator = removeList.iterator(); while (iterator.hasNext()) newClassPath.remove(iterator.next()); } private void addJRE() { IClasspathEntry[] jre = EclipseResourceUtil.getDefaultJRELibrary(); for (int i = 0; i < jre.length; i++) if (!entryAlreadyExists(jre[i], newClassPath)) newClassPath.add(jre[i]); } private void addLibJars() { XModelObject fss = FileSystemsHelper.getFileSystems(model); XModelObject[] children = fss == null ? new XModelObject[0] : fss.getChildren("FileSystemJar"); //$NON-NLS-1$ List<String> srcPaths = new ArrayList<String>(); for (int i = 0; i < children.length; i++) { if(XModelObjectConstants.TRUE.equals(children[i].get(FileSystemsLoader.IS_ADDED_TO_CLASSPATH))) continue; String osPath = XModelObjectUtil.getExpandedValue(children[i], XModelObjectConstants.ATTR_NAME_LOCATION, null); if (osPath != null && !"".equals(osPath) && new File(osPath).isFile()) srcPaths.add(osPath); //$NON-NLS-1$ children[i].set(FileSystemsLoader.IS_ADDED_TO_CLASSPATH, XModelObjectConstants.TRUE); } // Leave it to WTP // Iterator iterator = srcPaths.iterator(); // while (iterator.hasNext()) { // IClasspathEntry entry = createNewClasspathEntry(iterator.next().toString(), IClasspathEntry.CPE_LIBRARY); // if (!entryAlreadyExists(entry, newClassPath)) newClassPath.add(entry); // } } private void createClassPath() { addJRE(); addLibJars(); addServletSupport(); } static SpecialWizard addServletSupportWizard = SpecialWizardFactory.createSpecialWizard("org.jboss.tools.jst.web.project.AddServletSupportWizard"); //$NON-NLS-1$ private void addServletSupport() { // if(addServletSupportWizard == null) return; // addServletSupportWizard.setObject(this); // addServletSupportWizard.execute(); } private boolean entryAlreadyExists(IClasspathEntry entry, List entryList) { boolean result = (entry != null && entryList.contains(entry)); if(result) return true; IClasspathEntry resolvedEntry = JavaCore.getResolvedClasspathEntry(entry); IPath resolvedEntryPath = (resolvedEntry != null) ? resolvedEntry.getPath() : null; if (resolvedEntryPath == null) return false; Iterator iterator = entryList.iterator(); while (iterator.hasNext() && !result) { IClasspathEntry tmpEntry = (IClasspathEntry)iterator.next(); IClasspathEntry tmpResolvedEntry; if (tmpEntry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) { IClasspathContainer container; try { container = JavaCore.getClasspathContainer(tmpEntry.getPath(), javaProject); } catch (JavaModelException e) { container = null; } if (container == null) continue; IClasspathEntry containerEntries[] = container.getClasspathEntries(); for (int i = 0; i < containerEntries.length && !result; i++) { tmpResolvedEntry = JavaCore.getResolvedClasspathEntry(containerEntries[i]); result = (tmpResolvedEntry != null && resolvedEntryPath.equals(tmpResolvedEntry.getPath())); } } else { tmpResolvedEntry = JavaCore.getResolvedClasspathEntry(tmpEntry); result = (tmpResolvedEntry != null && resolvedEntryPath.equals(tmpResolvedEntry.getPath())); } } if(entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) { IClasspathContainer container; try { container = JavaCore.getClasspathContainer(entry.getPath(), javaProject); } catch (JavaModelException e) { container = null; } if (container != null) { IClasspathEntry[] containerEntries = container.getClasspathEntries(); for (int i = 0; i < containerEntries.length; i++) { if(entryAlreadyExists(containerEntries[i], entryList)) return true; } } } return result; } private IClasspathEntry createNewClasspathEntry(String location, int entryKind) { IPath entryPath = EclipseResourceUtil.getRelativePath(project, location); return createNewClasspathEntry(entryPath, entryKind); } public IClasspathEntry createNewClasspathEntry(IPath path, int entryKind) { switch(entryKind) { case IClasspathEntry.CPE_SOURCE: return JavaCore.newSourceEntry(path); case IClasspathEntry.CPE_LIBRARY: return JavaCore.newLibraryEntry(path, null, null); case IClasspathEntry.CPE_VARIABLE: return JavaCore.newVariableEntry(path, null, null); case IClasspathEntry.CPE_CONTAINER: return JavaCore.newContainerEntry(path); default: return null; } } public void registerEntry(IClasspathEntry entry) { if (!entryAlreadyExists(entry, newClassPath)) newClassPath.add(entry); } }