/*******************************************************************************
* 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.jsf.web.helpers.context;
import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.jboss.tools.common.meta.action.impl.handlers.DefaultCreateHandler;
import org.jboss.tools.common.model.XModel;
import org.jboss.tools.common.model.XModelConstants;
import org.jboss.tools.common.model.XModelException;
import org.jboss.tools.common.model.XModelObject;
import org.jboss.tools.common.model.filesystems.FileSystemsHelper;
import org.jboss.tools.common.model.filesystems.impl.FileAnyImpl;
import org.jboss.tools.common.model.filesystems.impl.Libs;
import org.jboss.tools.common.model.util.EclipseResourceUtil;
import org.jboss.tools.common.model.util.XModelObjectLoaderUtil;
import org.jboss.tools.common.util.FileUtil;
import org.jboss.tools.jsf.JSFModelPlugin;
import org.jboss.tools.jsf.model.FacesProcessImpl;
import org.jboss.tools.jsf.model.JSFConstants;
import org.jboss.tools.jsf.project.JSF2Util;
import org.jboss.tools.jst.web.context.IImportWebProjectContext;
import org.jboss.tools.jst.web.model.helpers.WebAppHelper;
import org.jboss.tools.jst.web.project.WebModuleConstants;
public class AdoptJSFProjectFinisher {
protected IImportWebProjectContext context = null;
protected XModel model = null;
protected XModelObject web;
protected XModelObject fss;
protected String workspace = null;
protected String srclocation = "";
protected Map<String,XModelObject> filesystems = new HashMap<String,XModelObject>();
public void setContext(XModel model, IImportWebProjectContext context) {
this.context = context;
this.model = model;
}
public void execute() throws XModelException {
filesystems.clear();
workspace = context.getWebInfLocation();
fss = model.getByPath("FileSystems");
web = model.getByPath("Web");
createBuildFileSystem();
createWebInfFileSystem();
createWebXMLFileSystem();
createWebRootFileSystem();
createSrcFileSystems();
createClassesFileSystem();
createLibFileSystems();
String an = context.getApplicationName();
if (an == null)
an = context.getProjectName();
fss.setAttributeValue("application name", an);
fss.setModified(true);
appendModules();
modifyWebXML();
model.save();
}
private XModelObject getOrCreateFileSystem(String name, String location, boolean req) {
return getOrCreateFileSystem(name, location, null, req, false);
}
private XModelObject getOrCreateFileSystem(String name, String location, String info) {
return getOrCreateFileSystem(name, location, info, true, false);
}
private XModelObject getOrCreateFileSystem(String name, String location,
String info, boolean req, boolean jar) {
XModelObject fs = (req) ? null : (XModelObject) filesystems.get(location);
if (fs != null)
return fs;
String entity = (!jar) ? "FileSystemFolder" : "FileSystemJar";
fs = model.createModelObject(entity, null);
fs.setAttributeValue("name", name);
fs.setAttributeValue("location", location);
if (info != null)
fs.setAttributeValue("info", info);
fss.addChild(fs);
filesystems.put(location, fs);
return fs;
}
private void createWebInfFileSystem() {
getOrCreateFileSystem("WEB-INF", XModelConstants.WORKSPACE_REF, true);
}
private void createWebXMLFileSystem() {
File webxml = new File(context.getWebXmlLocation());
String webxmlfolder = webxml.getParent();
String relative = getRelativePath(workspace, webxmlfolder);
if (relative == null || relative.startsWith("/..")) {
String loc = (relative == null) ? webxmlfolder
: XModelConstants.WORKSPACE_REF + relative;
getOrCreateFileSystem("web-xml", loc, true);
web.setAttributeValue("model path", "/" + webxml.getName());
} else {
web.setAttributeValue("model path", relative + "/"
+ webxml.getName());
}
}
private XModelObject getDefaultModule() {
XModelObject[] ms = context.getModules();
for (int i = 0; i < ms.length; i++) {
if (ms[i].getAttributeValue("name").length() == 0)
return ms[i];
}
return null;
}
private void createWebRootFileSystem() {
XModelObject m = getDefaultModule();
if (m == null)
return;
String loc = getFileSystemLocation(workspace, m
.getAttributeValue("root"));
m.setAttributeValue(WebModuleConstants.ATTR_ROOT_FS, "WEB-ROOT");
getOrCreateFileSystem("WEB-ROOT", loc, "Content-Type=Web");
}
private void createSrcFileSystems() {
createWebRootSrcFileSystem();
}
private void createWebRootSrcFileSystem() {
XModelObject m = getDefaultModule();
String[] srcs = context.getExistingSources();
List<String> l = new ArrayList<String>();
if (srcs != null)
for (int i = 0; i < srcs.length; i++)
l.add(srcs[i]);
String s = m.getAttributeValue("java src");
if (!l.contains(s))
l.add(s);
srcs = l.toArray(new String[0]);
String srcAttr = "";
int j = 0;
for (int i = 0; i < srcs.length; i++) {
srclocation = srcs[i];
if (srclocation.length() == 0)
continue;
String loc = getFileSystemLocation(workspace, srclocation);
++j;
String fsn = (j == 1) ? "src" : "src" + j;
getOrCreateFileSystem(fsn, loc, false);
if (j > 1)
srcAttr += ",";
srcAttr += fsn;
}
m.setAttributeValue("src file system", srcAttr);
}
private void createLibFileSystems() {
String lib = context.getLibLocation();
if (lib == null || lib.length() == 0)
return;
File f = new File(lib);
if (!f.isDirectory())
return;
String loc = getFileSystemLocation(workspace, lib);
getOrCreateFileSystem("lib", loc, true);
File[] jars = f.listFiles(new FileFilter() {
public boolean accept(File file) {
if (!file.isFile())
return false;
String name = file.getName().toLowerCase();
return name.endsWith(".jar") || name.endsWith(".zip");
}
});
if (jars != null)
for (int i = 0; i < jars.length; i++) {
String n = jars[i].getName();
getOrCreateFileSystem(Libs.LIB_PREFIX + n, loc + "/" + n, "hidden=yes",
true, true);
}
}
private void createClassesFileSystem() {
String classes = context.getClassesLocation();
if(classes == null || classes.length() == 0) return;
if(!new File(classes).isDirectory()) return;
String loc = getFileSystemLocation(workspace, classes);
getOrCreateFileSystem("classes", loc, false);
}
private void createBuildFileSystem() {
String build = context.getBuildXmlLocation();
if(build == null || build.length() == 0) return;
File f = new File(build);
if(f.isFile()) {
f = f.getParentFile();
build = f.getAbsolutePath();
}
if(!new File(build).isDirectory()) return;
String loc = getFileSystemLocation(workspace, build);
getOrCreateFileSystem("build", loc, false);
}
protected void appendModules() {
XModelObject[] ms = web.getChildren("WebJSFModule");
for (int i = 0; i < ms.length; i++) ms[i].removeFromParent();
ms = context.getModules();
for (int i = 0; i < ms.length; i++) web.addChild(ms[i]);
web.setModified(true);
}
public static String getRelativePath(String rootpath, String path) {
return FileUtil.getRelativePath(rootpath, path);
}
public static String getFileSystemLocation(String rootpath, String path) {
path = path.replace('\\', '/');
String relative = getRelativePath(rootpath, path);
return (relative == null) ? path : XModelConstants.WORKSPACE_REF + relative;
}
void modifyWebXML() throws XModelException {
IProject project = EclipseResourceUtil.getProject(model.getRoot());
boolean isJSF2 = false;
try {
isJSF2 = JSF2Util.isJSF2(project);
if(!isJSF2) isJSF2 = isJSF2a();
} catch (CoreException e) {
JSFModelPlugin.getPluginLog().logError(e);
return;
}
if(isJSF2) return;
XModelObject webxml = WebAppHelper.getWebApp(model);
XModelObject servlet = WebAppHelper.findServlet(webxml,
JSFConstants.FACES_SERVLET_CLASS, "Faces Config");
if (servlet == null) {
servlet = WebAppHelper.findOrCreateServlet(webxml,
JSFConstants.FACES_SERVLET_CLASS, "Faces Config", -1);
}
String servletName = servlet.getAttributeValue("servlet-name");
XModelObject mapping = WebAppHelper.findServletMapping(webxml,
servletName);
if (mapping == null) {
mapping = WebAppHelper.findOrCreateServletMapping(webxml, servletName);
}
XModelObject facesConfig = model.getByPath("/faces-config.xml");
if (facesConfig == null) {
XModelObject webinf = FileSystemsHelper.getWebInf(model);
if (webinf != null && !isJSF2) {
facesConfig = XModelObjectLoaderUtil.createValidObject(model, JSFConstants.ENT_FACESCONFIG_12);
DefaultCreateHandler.addCreatedObject(webinf, facesConfig, -1);
FacesProcessImpl process = (FacesProcessImpl)facesConfig.getChildByPath(JSFConstants.ELM_PROCESS);
if(process != null) process.firePrepared();
}
}
}
private boolean isJSF2a() {
XModelObject fs = model.getByPath("FileSystems/lib-jsf-api.jar");
if(fs == null) return false;
XModelObject m = fs.getChildByPath("META-INF/MANIFEST.MF");
if(!(m instanceof FileAnyImpl)) return false;
String content = ((FileAnyImpl)m).getAsText();
String attr = "Implementation-Version";
int i = content.indexOf(attr);
if(i < 0) return false;
i += attr.length();
for (int j = i; j < content.length(); j++) {
char ch = content.charAt(j);
if(!Character.isDigit(ch)) {
continue;
}
return ch > '1';
}
return false;
}
}