package org.jboss.tools.jsf.project; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.wst.common.componentcore.ComponentCore; import org.eclipse.wst.common.componentcore.resources.IVirtualComponent; import org.jboss.tools.common.model.XModel; import org.jboss.tools.common.model.XModelConstants; import org.jboss.tools.common.model.XModelObject; import org.jboss.tools.common.model.XModelObjectConstants; import org.jboss.tools.common.model.filesystems.FileSystemsHelper; import org.jboss.tools.common.model.impl.XModelImpl; import org.jboss.tools.common.model.project.IAutoLoad; import org.jboss.tools.common.model.util.EclipseResourceUtil; import org.jboss.tools.common.model.util.XModelObjectUtil; import org.jboss.tools.common.util.FileUtil; import org.jboss.tools.jsf.model.pv.JSFProjectsTree; import org.jboss.tools.jst.web.WebUtils; import org.jboss.tools.jst.web.model.pv.WebProjectNode; public class JSFAutoLoad implements IAutoLoad, XModelObjectConstants { static String WEB_INF = "WEB-INF"; //$NON-NLS-1$ static String WEB_ROOT = "WEB-ROOT"; //$NON-NLS-1$ public void load(XModel model) { XModelObject fs = FileSystemsHelper.getFileSystems(model); IProject project = EclipseResourceUtil.getProject(fs); if(project == null) return; fs.setAttributeValue("application name", project.getName()); //$NON-NLS-1$ XModelObject s = createFileSystemFolder(model, project.getName(), project.getLocation().toString()); fs.addChild(s); XModelObject webinf = createFileSystemFolder(model, WEB_INF, XModelConstants.WORKSPACE_REF); fs.addChild(webinf); String webInfLocation = XModelObjectUtil.expand(XModelConstants.WORKSPACE_REF, model, null); List<String> webRootLocations = getWebRootPaths(project, webInfLocation); int i = 0; for (String webRootLocation: webRootLocations) { String name = WEB_ROOT; if(i > 0) name += "-" + i; XModelObject webroot = createFileSystemFolder(model, name, webRootLocation); fs.addChild(webroot); i++; } XModelObject lib = createFileSystemFolder(model, "lib", XModelConstants.WORKSPACE_REF + "/lib"); //$NON-NLS-1$ //$NON-NLS-2$ fs.addChild(lib); } XModelObject createFileSystemFolder(XModel model, String name, String location) { XModelObject f = model.createModelObject(ENT_FILE_SYSTEM_FOLDER, null); f.setAttributeValue(ATTR_NAME, name); f.setAttributeValue(ATTR_NAME_LOCATION, location); return f; } public void update(XModel model) { XModelObject fs = FileSystemsHelper.getFileSystems(model); IProject project = EclipseResourceUtil.getProject(fs); if(project == null) return; String webInfLocation = XModelObjectUtil.expand(XModelConstants.WORKSPACE_REF, model, null); List<String> webRootLocations = getWebRootPaths(project, webInfLocation); boolean modified = false; XModelObject webinf = fs.getChildByPath(WEB_INF); String rWebInfLocation = getWebInfPath(project, webInfLocation); if(rWebInfLocation != null) { if(webinf != null && !rWebInfLocation.equals(webinf.getAttributeValue(ATTR_NAME_LOCATION))) { webinf.removeFromParent(); webinf = null; modified = true; } if(webinf == null) { webinf = createFileSystemFolder(model, WEB_INF, rWebInfLocation); fs.addChild(webinf); modified = true; } } else if(webinf != null) { webinf.removeFromParent(); modified = true; } List<XModelObject> existingRoots = getExistingWebRoots(fs); boolean rootsChanged = rootsChanged(webRootLocations, existingRoots); if(rootsChanged) { modified = true; for (XModelObject c: existingRoots) { c.removeFromParent(); } int i = 0; for (String webRootLocation: webRootLocations) { String name = WEB_ROOT; if(i > 0) name += "-" + i; XModelObject webroot = createFileSystemFolder(model, name, webRootLocation); fs.addChild(webroot); i++; } } if(modified) { ((XModelImpl)fs.getModel()).fireStructureChanged(fs); WebProjectNode n = JSFProjectsTree.getProjectsRoot(model); if(n != null) { n.invalidate(); } } } boolean rootsChanged(List<String> webRootLocations, List<XModelObject> rs) { if(webRootLocations.size() != rs.size()) return true; for (int i = 0; i < webRootLocations.size(); i++) { String s = webRootLocations.get(i); XModelObject o = rs.get(i); if(!o.getAttributeValue(ATTR_NAME_LOCATION).equals(s)) { return true; } } return false; } List<XModelObject> getExistingWebRoots(XModelObject fs) { List<XModelObject> result = new ArrayList<XModelObject>(); XModelObject[] cs = fs.getChildren(ENT_FILE_SYSTEM_FOLDER); for (XModelObject c: cs) { if(c.getAttributeValue(ATTR_NAME).startsWith(WEB_ROOT)) { result.add(c); } } return result; } static List<String> getWebRootPaths(IProject project, String webInfLocation) { List<String> result = new ArrayList<String>(); IContainer[] cs = WebUtils.getWebRootFolders(project); for (IContainer c: cs) { IPath path = c.getLocation(); if(path == null) continue; String webRootLocation = null; try { webRootLocation = path.toFile().getCanonicalPath().replace('\\', '/'); String relative = FileUtil.getRelativePath(webInfLocation, webRootLocation); if(relative != null) { webRootLocation = XModelConstants.WORKSPACE_REF + relative; } result.add(webRootLocation); } catch (IOException e) { continue; } } return result; } static String getWebInfPath(IProject project, String webInfLocation) { IVirtualComponent component = ComponentCore.createComponent(project); if(component != null && component.getRootFolder() != null) { String virtual = null; IContainer[] cs = WebUtils.getWebRootFolders(project, true); for (IContainer c: cs) { if(c.exists()) { IFolder f = c.getFolder(new Path("/WEB-INF")); //$NON-NLS-1$ if(f.exists()) { //If one of web roots contains WEB-INF, return it. try { String location = f.getLocation().toFile().getCanonicalPath().replace('\\', '/'); String relative = FileUtil.getRelativePath(webInfLocation, location); return (relative != null) ? XModelConstants.WORKSPACE_REF + relative : location; } catch (IOException e) { continue; } } else if(virtual == null) { //Find the first web root without WEB-INF, and return it if there is no web root with WEB-INF. //For advanced servers, WEB-INF folder is not required. try { String location = c.getLocation().toFile().getCanonicalPath().replace('\\', '/') + "/WEB-INF"; String relative = FileUtil.getRelativePath(webInfLocation, location); virtual = (relative != null) ? XModelConstants.WORKSPACE_REF + relative : location; } catch (IOException e) { continue; } } } } if(virtual != null) { return virtual; } } return null; } }